diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 4635bb780799b702e9fe5ee195ae9e8dd507223d..b38cc8f83dfd3b8d77a8d25a8447da9a69004a74 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1131,7 +1131,7 @@ function theme($hook, $variables = array()) {
     // new variable to track that.
     if (!isset($variables['directory'])) {
       $default_template_variables = array();
-      template_preprocess($default_template_variables, $hook);
+      template_preprocess($default_template_variables, $hook, $info);
       $variables += $default_template_variables;
     }
     if (!isset($default_attributes)) {
diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php
index 072bfb0ea0e0dfe2baffb8b0f4215a4590ab97ce..f8dd876f7205455dec614e8ace7026a2bb6d5680 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php
@@ -161,6 +161,14 @@ function testTemplateOverride() {
     $this->assertText('Success: Template overridden.', 'Template overridden by defined \'template\' filename.');
   }
 
+  /**
+   * Ensures a theme template can override a theme function.
+   */
+  function testFunctionOverride() {
+    $this->drupalGet('theme-test/function-template-overridden');
+    $this->assertText('Success: Template overrides theme function.', 'Theme function overridden by test_theme template.');
+  }
+
   /**
    * Test the list_themes() function.
    */
diff --git a/core/modules/system/tests/modules/theme_test/lib/Drupal/theme_test/ThemeTestController.php b/core/modules/system/tests/modules/theme_test/lib/Drupal/theme_test/ThemeTestController.php
new file mode 100644
index 0000000000000000000000000000000000000000..c790a840ff80bcc13b5bb06010759afb9c238e85
--- /dev/null
+++ b/core/modules/system/tests/modules/theme_test/lib/Drupal/theme_test/ThemeTestController.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\theme_test\ThemeTestController.
+ */
+
+namespace Drupal\theme_test;
+
+use Drupal\Core\Controller\ControllerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Controller routines for theme test routes.
+ */
+class ThemeTestController implements ControllerInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static();
+  }
+
+  /**
+   * Menu callback for testing that a theme template overrides a theme function.
+   */
+  function functionTemplateOverridden() {
+    return array(
+      '#theme' => 'theme_test_function_template_override',
+    );
+  }
+
+}
diff --git a/core/modules/system/tests/modules/theme_test/theme_test.module b/core/modules/system/tests/modules/theme_test/theme_test.module
index ca8439d49c5e41dc685be1f954706e8b874e194e..07666fdfcda2ef67a8b573b02b257c4e3efe088c 100644
--- a/core/modules/system/tests/modules/theme_test/theme_test.module
+++ b/core/modules/system/tests/modules/theme_test/theme_test.module
@@ -24,6 +24,9 @@ function theme_test_theme($existing, $type, $theme, $path) {
   $items['theme_test_render_element_children'] = array(
     'render element' => 'element',
   );
+  $items['theme_test_function_template_override'] = array(
+    'variables' => array(),
+  );
   return $items;
 }
 
@@ -71,6 +74,10 @@ function theme_test_menu() {
     'access callback' => TRUE,
     'type' => MENU_CALLBACK,
   );
+  $items['theme-test/function-template-overridden'] = array(
+    'theme callback' => '_theme_custom_theme',
+    'route_name' => 'function_template_override',
+  );
   return $items;
 }
 
@@ -157,6 +164,13 @@ function theme_theme_test_foo($variables) {
   return $variables['foo'];
 }
 
+/**
+ * Theme function for testing theme('theme_test_function_template_override').
+ */
+function theme_theme_test_function_template_override($variables) {
+  return 'theme_test_function_template_override test failed.';
+}
+
 /**
  * Process variables for theme-test-render-element.tpl.php.
  */
diff --git a/core/modules/system/tests/modules/theme_test/theme_test.routing.yml b/core/modules/system/tests/modules/theme_test/theme_test.routing.yml
new file mode 100644
index 0000000000000000000000000000000000000000..866171e2be0d1038cef352e9e794ee0c195db7e2
--- /dev/null
+++ b/core/modules/system/tests/modules/theme_test/theme_test.routing.yml
@@ -0,0 +1,6 @@
+function_template_override:
+  pattern: '/theme-test/function-template-overridden'
+  defaults:
+    _content: '\Drupal\theme_test\ThemeTestController::functionTemplateOverridden'
+  requirements:
+    _permission: 'access content'
diff --git a/core/modules/system/tests/themes/test_theme/theme-test-function-template-override.html.twig b/core/modules/system/tests/themes/test_theme/theme-test-function-template-override.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..15f90eb361c7c3db35dd6d4daa1b6cb134a8e855
--- /dev/null
+++ b/core/modules/system/tests/themes/test_theme/theme-test-function-template-override.html.twig
@@ -0,0 +1,2 @@
+{# Output for Theme API test #}
+Success: Template overrides theme function.