diff --git a/core/lib/Drupal/Core/Controller/HtmlPageController.php b/core/lib/Drupal/Core/Controller/HtmlPageController.php
index d87b3ed..f5649dc 100644
--- a/core/lib/Drupal/Core/Controller/HtmlPageController.php
+++ b/core/lib/Drupal/Core/Controller/HtmlPageController.php
@@ -66,8 +66,18 @@ public function content(Request $request, $_content) {
       );
     }
     // If no title was returned fall back to one defined in the route.
-    if (!isset($page_content['#title']) && $request->attributes->has('_title')) {
-      $page_content['#title'] = $request->attributes->get('_title');
+    if (!isset($page_content['#title'])) {
+      // A dynamic title takes priority.
+      if ($request->attributes->has('_title_callback')) {
+        $callback = $request->attributes->get('_title_callback');
+        $callable = $this->controllerResolver->getControllerFromDefinition($callback);
+        $arguments = $this->controllerResolver->getArguments($request, $callable);
+        $page_content['#title'] = call_user_func_array($callable, $arguments);
+      }
+      elseif ($request->attributes->has('_title')) {
+        // Fall back to a static string from the route.
+        $page_content['#title'] = $request->attributes->get('_title');
+      }
     }
 
     $response = new Response(drupal_render_page($page_content));
diff --git a/core/modules/aggregator/aggregator.module b/core/modules/aggregator/aggregator.module
index e5321d4..4fcb546 100644
--- a/core/modules/aggregator/aggregator.module
+++ b/core/modules/aggregator/aggregator.module
@@ -90,7 +90,6 @@ function aggregator_theme() {
  */
 function aggregator_menu() {
   $items['admin/config/services/aggregator'] = array(
-    'title' => 'Feed aggregator',
     'description' => "Configure which content your site aggregates from other sites, how often it polls them, and how they're categorized.",
     'route_name' => 'aggregator_admin_overview',
     'weight' => 10,
diff --git a/core/modules/aggregator/aggregator.routing.yml b/core/modules/aggregator/aggregator.routing.yml
index cadbb14..f5ff870 100644
--- a/core/modules/aggregator/aggregator.routing.yml
+++ b/core/modules/aggregator/aggregator.routing.yml
@@ -2,6 +2,7 @@ aggregator_admin_overview:
   pattern: 'admin/config/services/aggregator'
   defaults:
     _content: '\Drupal\aggregator\Controller\AggregatorController::adminOverview'
+    _title: 'Feed aggregator'
   requirements:
     _permission: 'administer news feeds'
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php b/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php
index 942fa9e..08b8691 100644
--- a/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php
@@ -128,14 +128,29 @@ function testTitleXSS() {
   /**
    * Tests the page title of render arrays.
    *
-   * @see \Drupal\test_page_test\Controller\Test::renderTitle()
+   * @see \Drupal\test_page_test\Controller\Test
    */
-  public function testRenderTitle() {
+  public function testRoutingTitle() {
+    // Test the '#title' render array attribute.
     $this->drupalGet('test-render-title');
 
     $this->assertTitle('Foo | Drupal');
     $result = $this->xpath('//h1');
     $this->assertEqual('Foo', (string) $result[0]);
+
+    // Test the static '_title' route option.
+    $this->drupalGet('test-static-title');
+
+    $this->assertTitle('Static title | Drupal');
+    $result = $this->xpath('//h1');
+    $this->assertEqual('Static title', (string) $result[0]);
+
+    // Test the dynamic '_title_callback' route option.
+    $this->drupalGet('test-dynamic-title');
+
+    $this->assertTitle('Dynamic title | Drupal');
+    $result = $this->xpath('//h1');
+    $this->assertEqual('Dynamic title', (string) $result[0]);
   }
 
 }
diff --git a/core/modules/system/tests/modules/test_page_test/lib/Drupal/test_page_test/Controller/Test.php b/core/modules/system/tests/modules/test_page_test/lib/Drupal/test_page_test/Controller/Test.php
index 850ca2d..d73838c 100644
--- a/core/modules/system/tests/modules/test_page_test/lib/Drupal/test_page_test/Controller/Test.php
+++ b/core/modules/system/tests/modules/test_page_test/lib/Drupal/test_page_test/Controller/Test.php
@@ -26,4 +26,26 @@ public function renderTitle() {
     return $build;
   }
 
+  /**
+   * Returns a 'dynamic' title for the '_title_callback' route option.
+   *
+   * @return string
+   *   The page title.
+   */
+  public function dynamicTitle() {
+    return 'Dynamic title';
+  }
+
+  /**
+   * Returns a generic page render array for title tests.
+   *
+   * @return array
+   *   A render array as expected by drupal_render()
+   */
+  public function renderPage() {
+    return array(
+      '#markup' => 'Content',
+    );
+  }
+
 }
diff --git a/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml b/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml
index 0f45d10..2afeb19 100644
--- a/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml
+++ b/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml
@@ -4,3 +4,19 @@ test_page_render_title:
     _content: 'Drupal\test_page_test\Controller\Test::renderTitle'
   requirements:
     _access: 'TRUE'
+
+test_page_static_title:
+  pattern: '/test-static-title'
+  defaults:
+    _content: 'Drupal\test_page_test\Controller\Test::renderPage'
+    _title: 'Static title'
+  requirements:
+    _access: 'TRUE'
+
+test_page_dynamic_title:
+  pattern: '/test-dynamic-title'
+  defaults:
+    _content: 'Drupal\test_page_test\Controller\Test::renderPage'
+    _title_callback: 'Drupal\test_page_test\Controller\Test::dynamicTitle'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/user/lib/Drupal/user/Controller/UserController.php b/core/modules/user/lib/Drupal/user/Controller/UserController.php
index cd63cb0..1254060 100644
--- a/core/modules/user/lib/Drupal/user/Controller/UserController.php
+++ b/core/modules/user/lib/Drupal/user/Controller/UserController.php
@@ -7,7 +7,9 @@
 
 namespace Drupal\user\Controller;
 
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\user\Form\UserLoginForm;
+use Drupal\Component\Utility\Xss;
 use Symfony\Component\DependencyInjection\ContainerAware;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Request;
@@ -42,6 +44,19 @@ public function userPage(Request $request) {
   }
 
   /**
+   * Route title callback.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $user
+   *   The user account.
+   *
+   * @return string
+   *   The user account name.
+   */
+  public function userTitle(EntityInterface $user = NULL) {
+    return $user ? Xss::filter($user->getUsername()) : '';
+  }
+
+  /**
    * Logs the current user out.
    *
    * @param \Symfony\Component\HttpFoundation\Request $request
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 91e7ee1..b29e904 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -913,15 +913,6 @@ function user_menu() {
     'type' => MENU_DEFAULT_LOCAL_TASK,
   );
 
-  $items['user/%user'] = array(
-    'title' => 'My account',
-    'title callback' => 'user_page_title',
-    'title arguments' => array(1),
-    'page callback' => 'user_view_page',
-    'page arguments' => array(1),
-    'access callback' => 'entity_page_access',
-    'access arguments' => array(1),
-  );
   $items['user/%user/view'] = array(
     'title' => 'View',
     'type' => MENU_DEFAULT_LOCAL_TASK,
@@ -1079,13 +1070,6 @@ function user_menu_title() {
 }
 
 /**
- * Menu item title callback - use the user name.
- */
-function user_page_title(UserInterface $account = NULL) {
-  return $account ? $account->getUsername() : '';
-}
-
-/**
  * Try to validate the user's login credentials locally.
  *
  * @param $name
diff --git a/core/modules/user/user.routing.yml b/core/modules/user/user.routing.yml
index 90570ea..6539a7c 100644
--- a/core/modules/user/user.routing.yml
+++ b/core/modules/user/user.routing.yml
@@ -96,6 +96,14 @@ user_page:
   requirements:
     _access: 'TRUE'
 
+user_view:
+  pattern: '/user/{user}'
+  defaults:
+    _entity_view: 'user.full'
+    _title_callback: 'Drupal\user\Controller\UserController::userTitle'
+  requirements:
+    _entity_access: 'user.view'
+
 user_login:
   pattern: '/user/login'
   defaults:
