diff --git a/core/core.services.yml b/core/core.services.yml
index 7c1e473ac49f03a3790c8bd1424cd1d8712c7ad8..5e63508f6c4ba1d59515a9d22f936aa22a082f41 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -909,6 +909,11 @@ services:
     tags:
       - { name: paramconverter }
     arguments: ['@entity.manager']
+  paramconverter.entity_revision:
+    class: Drupal\Core\ParamConverter\EntityRevisionParamConverter
+    tags:
+      - { name: paramconverter }
+    arguments: ['@entity_type.manager']
   paramconverter.configentity_admin:
     class: Drupal\Core\ParamConverter\AdminPathConfigEntityConverter
     tags:
@@ -963,6 +968,10 @@ services:
     class: Drupal\Core\Entity\Enhancer\EntityRouteEnhancer
     tags:
       - { name: route_enhancer, priority: 20 }
+  route_enhancer.entity_revision:
+    class: Drupal\Core\Routing\Enhancer\EntityRevisionRouteEnhancer
+    tags:
+      - { name: route_enhancer }
   route_special_attributes_subscriber:
     class: Drupal\Core\EventSubscriber\SpecialAttributesRouteSubscriber
     tags:
diff --git a/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php b/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php
index d416e3aadb253db65fcf94fb10003ac6d9328a60..435aa5793638fa68ee53823cb89e0d6d6080ec4f 100644
--- a/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php
+++ b/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php
@@ -104,8 +104,25 @@ public function view(EntityInterface $_entity, $view_mode = 'full') {
     $page['#entity_type'] = $_entity->getEntityTypeId();
     $page['#' . $page['#entity_type']] = $_entity;
 
-
     return $page;
   }
 
+  /**
+   * Provides a page to render a single entity revision.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $_entity_revision
+   *   The Entity to be rendered. Note this variable is named $_entity_revision
+   *   rather than $entity to prevent collisions with other named placeholders
+   *   in the route.
+   * @param string $view_mode
+   *   (optional) The view mode that should be used to display the entity.
+   *   Defaults to 'full'.
+   *
+   * @return array
+   *   A render array.
+   */
+  public function viewRevision(EntityInterface $_entity_revision, $view_mode = 'full') {
+    return $this->view($_entity_revision, $view_mode);
+  }
+
 }
diff --git a/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php b/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php
index 81ffb6790238fd6c6431e25c28378969ca667a9b..882c61d6791f0e2e0cbd8f7dde5d82e5ff90284e 100644
--- a/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php
+++ b/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php
@@ -68,6 +68,17 @@ function testEntityViewController() {
       $this->assertRaw('full');
     }
 
+    // Test viewing a revisionable entity.
+    $entity_test_rev = $this->createTestEntity('entity_test_rev');
+    $entity_test_rev->save();
+    $entity_test_rev->name->value = 'rev 2';
+    $entity_test_rev->setNewRevision(TRUE);
+    $entity_test_rev->isDefaultRevision(TRUE);
+    $entity_test_rev->save();
+    $this->drupalGet('entity_test_rev/' . $entity_test_rev->id() . '/revision/' . $entity_test_rev->revision_id->value . '/view');
+    $this->assertRaw($entity_test_rev->label());
+    $this->assertRaw($get_label_markup($entity_test_rev->label()));
+
     // As entity_test IDs must be integers, make sure requests for non-integer
     // IDs return a page not found error.
     $this->drupalGet('entity_test/invalid');
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.routing.yml b/core/modules/system/tests/modules/entity_test/entity_test.routing.yml
index 542a14ebbcd4225e1b429152fc76c6f1cb81bff0..e4353c8771704b340c553e6bb45727dba399ab65 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.routing.yml
+++ b/core/modules/system/tests/modules/entity_test/entity_test.routing.yml
@@ -58,7 +58,13 @@ entity.entity_test.collection:
 entity.entity_test_rev.revision:
   path: '/entity_test_rev/{entity_test_rev}/revision/{entity_test_rev_revision}/view'
   defaults:
-    _entity_view: 'entity_test_rev'
+    _controller: '\Drupal\Core\Entity\Controller\EntityViewController::viewRevision'
+  options:
+    parameters:
+      entity_test_rev:
+        type: entity:entity_test_rev
+      entity_test_rev_revision:
+        type: entity_revision:entity_test_rev
   requirements:
     _access: 'TRUE'