diff --git a/core/modules/node/node.post_update.php b/core/modules/node/node.post_update.php
index 82d1f41fd3..e842c5b127 100644
--- a/core/modules/node/node.post_update.php
+++ b/core/modules/node/node.post_update.php
@@ -14,3 +14,10 @@ function node_removed_post_updates() {
     'node_post_update_node_revision_views_data' => '9.0.0',
   ];
 }
+
+/**
+ * Rebuild the node revision routes.
+ */
+function node_post_update_rebuild_node_revision_routes() {
+  // Empty update to rebuild routes.
+}
diff --git a/core/modules/node/node.routing.yml b/core/modules/node/node.routing.yml
index ac958ea242..962f21c0cc 100644
--- a/core/modules/node/node.routing.yml
+++ b/core/modules/node/node.routing.yml
@@ -60,6 +60,9 @@ entity.node.version_history:
     node: \d+
   options:
     _node_operation_route: TRUE
+    parameters:
+      node:
+        type: entity:node
 
 entity.node.revision:
   path: '/node/{node}/revisions/{node_revision}/view'
@@ -69,6 +72,12 @@ entity.node.revision:
   requirements:
     _access_node_revision: 'view'
     node: \d+
+  options:
+    parameters:
+      node:
+        type: entity:node
+      node_revision:
+        type: entity_revision:node
 
 node.revision_revert_confirm:
   path: '/node/{node}/revisions/{node_revision}/revert'
@@ -80,6 +89,11 @@ node.revision_revert_confirm:
     node: \d+
   options:
     _node_operation_route: TRUE
+    parameters:
+      node:
+        type: entity:node
+      node_revision:
+        type: entity_revision:node
 
 node.revision_revert_translation_confirm:
   path: '/node/{node}/revisions/{node_revision}/revert/{langcode}'
@@ -91,6 +105,11 @@ node.revision_revert_translation_confirm:
     node: \d+
   options:
     _node_operation_route: TRUE
+    parameters:
+      node:
+        type: entity:node
+      node_revision:
+        type: entity_revision:node
 
 node.revision_delete_confirm:
   path: '/node/{node}/revisions/{node_revision}/delete'
@@ -102,6 +121,11 @@ node.revision_delete_confirm:
     node: \d+
   options:
     _node_operation_route: TRUE
+    parameters:
+      node:
+        type: entity:node
+      node_revision:
+        type: entity_revision:node
 
 entity.node_type.collection:
   path: '/admin/structure/types'
diff --git a/core/modules/node/src/ContextProvider/NodeRouteContext.php b/core/modules/node/src/ContextProvider/NodeRouteContext.php
index 2a241cb481..e738cf6cb0 100644
--- a/core/modules/node/src/ContextProvider/NodeRouteContext.php
+++ b/core/modules/node/src/ContextProvider/NodeRouteContext.php
@@ -45,10 +45,8 @@ public function getRuntimeContexts(array $unqualified_context_ids) {
     if (($route_object = $this->routeMatch->getRouteObject())) {
       $route_contexts = $route_object->getOption('parameters');
       // Check for a node revision parameter first.
-      // @todo https://www.drupal.org/i/2730631 will allow to use the upcasted
-      //   node revision object.
-      if ($revision_id = $this->routeMatch->getRawParameter('node_revision')) {
-        $value = \Drupal::entityTypeManager()->getStorage('node')->loadRevision($revision_id);
+      if (isset($route_contexts['node_revision']) && $revision = $this->routeMatch->getParameter('node_revision')) {
+        $value = $revision;
       }
       elseif (isset($route_contexts['node']) && $node = $this->routeMatch->getParameter('node')) {
         $value = $node;
diff --git a/core/modules/node/src/Controller/NodeController.php b/core/modules/node/src/Controller/NodeController.php
index d87b298869..9fa131e7e4 100644
--- a/core/modules/node/src/Controller/NodeController.php
+++ b/core/modules/node/src/Controller/NodeController.php
@@ -112,33 +112,30 @@ public function addPage() {
   /**
    * Displays a node revision.
    *
-   * @param int $node_revision
-   *   The node revision ID.
+   * @param \Drupal\node\NodeInterface $node_revision
+   *   The node revision.
    *
    * @return array
    *   An array suitable for \Drupal\Core\Render\RendererInterface::render().
    */
-  public function revisionShow($node_revision) {
-    $node = $this->entityTypeManager()->getStorage('node')->loadRevision($node_revision);
-    $node = $this->entityRepository->getTranslationFromContext($node);
+  public function revisionShow(NodeInterface $node_revision) {
     $node_view_controller = new NodeViewController($this->entityTypeManager(), $this->renderer, $this->currentUser(), $this->entityRepository);
-    $page = $node_view_controller->view($node);
-    unset($page['nodes'][$node->id()]['#cache']);
+    $page = $node_view_controller->view($node_revision);
+    unset($page['nodes'][$node_revision->id()]['#cache']);
     return $page;
   }
 
   /**
    * Page title callback for a node revision.
    *
-   * @param int $node_revision
-   *   The node revision ID.
+   * @param \Drupal\node\NodeInterface $node_revision
+   *   The node revision.
    *
    * @return string
    *   The page title.
    */
-  public function revisionPageTitle($node_revision) {
-    $node = $this->entityTypeManager()->getStorage('node')->loadRevision($node_revision);
-    return $this->t('Revision of %title from %date', ['%title' => $node->label(), '%date' => $this->dateFormatter->format($node->getRevisionCreationTime())]);
+  public function revisionPageTitle(NodeInterface $node_revision) {
+    return $this->t('Revision of %title from %date', ['%title' => $node_revision->label(), '%date' => $this->dateFormatter->format($node_revision->getRevisionCreationTime())]);
   }
 
   /**
diff --git a/core/modules/node/src/Form/NodeRevisionDeleteForm.php b/core/modules/node/src/Form/NodeRevisionDeleteForm.php
index aefefde6cd..8d4554152c 100644
--- a/core/modules/node/src/Form/NodeRevisionDeleteForm.php
+++ b/core/modules/node/src/Form/NodeRevisionDeleteForm.php
@@ -8,6 +8,7 @@
 use Drupal\Core\Form\ConfirmFormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
+use Drupal\node\NodeInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -117,8 +118,8 @@ public function getConfirmText() {
   /**
    * {@inheritdoc}
    */
-  public function buildForm(array $form, FormStateInterface $form_state, $node_revision = NULL) {
-    $this->revision = $this->nodeStorage->loadRevision($node_revision);
+  public function buildForm(array $form, FormStateInterface $form_state, NodeInterface $node_revision = NULL) {
+    $this->revision = $node_revision;
     $form = parent::buildForm($form, $form_state);
 
     return $form;
diff --git a/core/modules/node/src/Form/NodeRevisionRevertForm.php b/core/modules/node/src/Form/NodeRevisionRevertForm.php
index da5cba023c..94a8f3b1a0 100644
--- a/core/modules/node/src/Form/NodeRevisionRevertForm.php
+++ b/core/modules/node/src/Form/NodeRevisionRevertForm.php
@@ -111,8 +111,8 @@ public function getDescription() {
   /**
    * {@inheritdoc}
    */
-  public function buildForm(array $form, FormStateInterface $form_state, $node_revision = NULL) {
-    $this->revision = $this->nodeStorage->loadRevision($node_revision);
+  public function buildForm(array $form, FormStateInterface $form_state, NodeInterface $node_revision = NULL) {
+    $this->revision = $node_revision;
     $form = parent::buildForm($form, $form_state);
 
     return $form;
