diff --git a/core/modules/system/src/Controller/BatchController.php b/core/modules/system/src/Controller/BatchController.php
index d14f987..9a63f0c 100644
--- a/core/modules/system/src/Controller/BatchController.php
+++ b/core/modules/system/src/Controller/BatchController.php
@@ -86,6 +86,7 @@ public function batchPage(Request $request) {
       drupal_set_page_content($output);
       $page = element_info('page');
       $page['#show_messages'] = FALSE;
+      $page['#title'] = $output['#title'];
 
       $page = $this->render($page);
 
@@ -94,6 +95,17 @@ public function batchPage(Request $request) {
   }
 
   /**
+   * The _title_callback for the system.batch_page.normal route.
+   *
+   * @return string
+   *   The page title.
+   */
+  public function batchPageTitle() {
+    $current_set = _batch_current_set();
+    return $current_set['title'];
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function render(array $output, $status_code = 200) {
diff --git a/core/modules/system/src/Tests/Batch/PageTest.php b/core/modules/system/src/Tests/Batch/PageTest.php
index 9c15510..59cee8e 100644
--- a/core/modules/system/src/Tests/Batch/PageTest.php
+++ b/core/modules/system/src/Tests/Batch/PageTest.php
@@ -53,4 +53,18 @@ function testBatchProgressPageTheme() {
     // page.
     $this->assertEqual(batch_test_stack(), array('seven'), 'A progressive batch correctly uses the theme of the page that started the batch.');
   }
+
+  /**
+   * Tests that the batch API progress page uses the correct theme.
+   */
+  function testBatchProgressPageTitle() {
+    // Visit an administrative page that runs a test batch, and check that the
+    // theme that was used during batch execution (which the batch callback
+    // function saved as a variable) matches the theme used on the
+    // administrative page.
+    $this->drupalGet('batch-test/test-title');
+    // The stack should contain the title shown on the progress page.
+    $this->assertEqual(batch_test_stack(), array('Batch Test'), 'The batch title is shown on the batch page.');
+    $this->assertText('Redirection successful.', 'Redirection after batch execution is correct.');
+  }
 }
diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml
index 35e17f7..c8c5c40 100644
--- a/core/modules/system/system.routing.yml
+++ b/core/modules/system/system.routing.yml
@@ -392,6 +392,7 @@ system.batch_page.normal:
   path: '/batch'
   defaults:
     _content: '\Drupal\system\Controller\BatchController::batchPage'
+    _title_callback: '\Drupal\system\Controller\BatchController::batchPageTitle'
   requirements:
     _access: 'TRUE'
   options:
@@ -401,6 +402,7 @@ system.batch_page.json:
   path: '/batch'
   defaults:
     _controller: '\Drupal\system\Controller\BatchController::batchPage'
+    _title_callback: '\Drupal\system\Controller\BatchController::batchPageTitle'
   requirements:
     _access: 'TRUE'
     _format: 'json'
diff --git a/core/modules/system/tests/modules/batch_test/batch_test.module b/core/modules/system/tests/modules/batch_test/batch_test.module
index b97f966..ac89aae 100644
--- a/core/modules/system/tests/modules/batch_test/batch_test.module
+++ b/core/modules/system/tests/modules/batch_test/batch_test.module
@@ -379,6 +379,21 @@ function _batch_test_theme_callback() {
 }
 
 /**
+ * Tests the progress page theme by performing a batch callback.
+ */
+function _batch_test_title_callback() {
+  // Because drupalGet() steps through the full progressive batch before
+  // returning control to the test function, we cannot test that the correct
+  // title is being used on the batch processing page by viewing that page
+  // directly. Instead, we save the title being used in a variable here, so
+  // that it can be loaded and inspected in the thread running the test.
+  $request = \Drupal::request();
+  $route_match = \Drupal::routeMatch();
+  $title = \Drupal::service('title_resolver')->getTitle($request, $route_match->getRouteObject());
+  batch_test_stack($title);
+}
+
+/**
  * Helper function: Stores or retrieves traced execution data.
  */
 function batch_test_stack($data = NULL, $reset = FALSE) {
diff --git a/core/modules/system/tests/modules/batch_test/batch_test.routing.yml b/core/modules/system/tests/modules/batch_test/batch_test.routing.yml
index afdba91..1d87a81 100644
--- a/core/modules/system/tests/modules/batch_test/batch_test.routing.yml
+++ b/core/modules/system/tests/modules/batch_test/batch_test.routing.yml
@@ -70,3 +70,10 @@ batch_test.test_theme:
     _content: '\Drupal\batch_test\Controller\BatchTestController::testThemeBatch'
   requirements:
     _access: 'TRUE'
+
+batch_test.test_title:
+  path: '/batch-test/test-title'
+  defaults:
+    _content: '\Drupal\batch_test\Controller\BatchTestController::testTitleBatch'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/system/tests/modules/batch_test/src/Controller/BatchTestController.php b/core/modules/system/tests/modules/batch_test/src/Controller/BatchTestController.php
index 2663531..dde0749 100644
--- a/core/modules/system/tests/modules/batch_test/src/Controller/BatchTestController.php
+++ b/core/modules/system/tests/modules/batch_test/src/Controller/BatchTestController.php
@@ -112,4 +112,22 @@ public function testThemeBatch() {
     return batch_process('batch-test/redirect');
   }
 
+  /**
+   * Runs a batch for testing the title shown on the progress page.
+   *
+   * @return \Symfony\Component\HttpFoundation\RedirectResponse|null
+   *   A redirect response if the batch is progressive. No return value otherwise.
+   */
+  public function testTitleBatch() {
+    batch_test_stack(NULL, TRUE);
+    $batch = array(
+      'title' => 'Batch Test',
+      'operations' => array(
+        array('_batch_test_title_callback', array()),
+      ),
+    );
+    batch_set($batch);
+    return batch_process('batch-test/redirect');
+  }
+
 }
