diff --git a/core/modules/system/src/Controller/BatchController.php b/core/modules/system/src/Controller/BatchController.php
index 761c32a08ddddc9933d2a2296976bb094d41405f..d234a4e7e79a5adda3cc220aeebfb275933f9cc4 100644
--- a/core/modules/system/src/Controller/BatchController.php
+++ b/core/modules/system/src/Controller/BatchController.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\system\Controller;
 
+use Drupal\Core\Batch\BatchStorageInterface;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\Request;
@@ -13,21 +14,14 @@
  */
 class BatchController implements ContainerInjectionInterface {
 
-  /**
-   * The app root.
-   *
-   * @var string
-   */
-  protected $root;
-
   /**
    * Constructs a new BatchController.
-   *
-   * @param string $root
-   *   The app root.
    */
-  public function __construct($root) {
-    $this->root = $root;
+  public function __construct(
+    protected string $root,
+    protected BatchStorageInterface $batchStorage
+  ) {
+    require_once $this->root . '/core/includes/batch.inc';
   }
 
   /**
@@ -35,7 +29,8 @@ public function __construct($root) {
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->getParameter('app.root')
+      $container->getParameter('app.root'),
+      $container->get('batch.storage'),
     );
   }
 
@@ -51,7 +46,6 @@ public static function create(ContainerInterface $container) {
    * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
    */
   public function batchPage(Request $request) {
-    require_once $this->root . '/core/includes/batch.inc';
     $output = _batch_page($request);
 
     if ($output === FALSE) {
@@ -87,7 +81,22 @@ public function batchPage(Request $request) {
    * @return string
    *   The page title.
    */
-  public function batchPageTitle() {
+  public function batchPageTitle(Request $request) {
+    $batch = &batch_get();
+
+    if (!($request_id = $request->query->get('id'))) {
+      return '';
+    }
+
+    // Retrieve the current state of the batch.
+    if (!$batch) {
+      $batch = $this->batchStorage->load($request_id);
+    }
+
+    if (!$batch) {
+      return '';
+    }
+
     $current_set = _batch_current_set();
     return !empty($current_set['title']) ? $current_set['title'] : '';
   }
diff --git a/core/modules/system/tests/src/Unit/Batch/BatchControllerTest.php b/core/modules/system/tests/src/Unit/Batch/BatchControllerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e68649fd37a67101f577c90d8fada7d76307a850
--- /dev/null
+++ b/core/modules/system/tests/src/Unit/Batch/BatchControllerTest.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\Tests\system\Unit\Batch;
+
+use Drupal\Core\Batch\BatchStorageInterface;
+use Drupal\system\Controller\BatchController;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Tests for the batch controller class.
+ *
+ * @coversDefaultClass \Drupal\system\Controller\BatchController
+ * @runTestsInSeparateProcesses
+ * @group system
+ */
+class BatchControllerTest extends UnitTestCase {
+
+  /**
+   * Tests title callback.
+   *
+   * @covers ::batchPageTitle
+   */
+  public function testBatchPageTitle() {
+    $batch_storage = $this->createMock(BatchStorageInterface::class);
+    $controller = new BatchController($this->root, $batch_storage);
+    require_once $this->root . '/core/includes/form.inc';
+    $this->assertSame('', $controller->batchPageTitle(new Request()));
+    // Test no batch loaded from storage and batch loaded from storage cases.
+    $batch = ['sets' => [['title' => 'foobar']], 'current_set' => 0];
+    $batch_storage->method('load')->will($this->onConsecutiveCalls(FALSE, $batch));
+    $this->assertSame('', $controller->batchPageTitle(new Request(['id' => 1234])));
+    $this->assertSame('foobar', $controller->batchPageTitle(new Request(['id' => 1234])));
+    // Test batch returned by &batch_get() call.
+    $batch = &batch_get();
+    $batch['sets']['0']['title'] = 'Updated title';
+    $this->assertSame('Updated title', $controller->batchPageTitle(new Request(['id' => 1234])));
+  }
+
+}