diff --git a/core/modules/node/src/NodeViewBuilder.php b/core/modules/node/src/NodeViewBuilder.php
index bcc580f..844a287 100644
--- a/core/modules/node/src/NodeViewBuilder.php
+++ b/core/modules/node/src/NodeViewBuilder.php
@@ -171,10 +171,20 @@ protected function alterBuild(array &$build, EntityInterface $entity, EntityView
     /** @var \Drupal\node\NodeInterface $entity */
     parent::alterBuild($build, $entity, $display, $view_mode, $langcode);
     if ($entity->id()) {
-      $build['#contextual_links']['node'] = array(
-        'route_parameters' =>array('node' => $entity->id()),
-        'metadata' => array('changed' => $entity->getChangedTime()),
-      );
+      if ($entity->isDefaultRevision()) {
+        $build['#contextual_links']['node'] = array(
+          'route_parameters' => array('node' => $entity->id()),
+          'metadata' => array('changed' => $entity->getChangedTime()),
+        );
+      }
+      else {
+        $build['#contextual_links']['node_revision'] = array(
+          'route_parameters' => array(
+            'node' => $entity->id(),
+            'node_revision' => $entity->getRevisionId(),
+          ),
+        );
+      }
     }
   }
 
diff --git a/core/modules/node/src/Tests/NodeRevisionsTest.php b/core/modules/node/src/Tests/NodeRevisionsTest.php
index de5b6d9..91c070a 100644
--- a/core/modules/node/src/Tests/NodeRevisionsTest.php
+++ b/core/modules/node/src/Tests/NodeRevisionsTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\node\Tests;
 
 use Drupal\node\Entity\Node;
+use Drupal\Component\Serialization\Json;
 
 /**
  * Create a node with revisions and test viewing, saving, reverting, and
@@ -19,6 +20,13 @@ class NodeRevisionsTest extends NodeTestBase {
   protected $nodes;
   protected $revisionLogs;
 
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('node', 'datetime', 'contextual');
+
   protected function setUp() {
     parent::setUp();
 
@@ -29,7 +37,8 @@ protected function setUp() {
         'revert page revisions',
         'delete page revisions',
         'edit any page content',
-        'delete any page content'
+        'delete any page content',
+        'access contextual links',
       )
     );
 
@@ -93,6 +102,18 @@ function testRevisions() {
     // Confirm that this is the default revision.
     $this->assertTrue($node->isDefaultRevision(), 'Third node revision is the default one.');
 
+    // Confirm that the "Edit" and "Delete" contextual links appear for the
+    // default revision.
+    $ids = array('node:node=' . $node->id() . ':changed=' . $node->getChangedTime());
+    $response = $this->renderContextualLinks($ids, "node/" . $node->id());
+    $json = Json::decode($response);
+    $this->verbose($json[$ids[0]]);
+
+    $this->assertTrue(strstr($json[$ids[0]], '<li class="entitynodeedit-form"><a href="' . base_path() . 'node/' . $node->id() . '/edit">Edit</a></li>'),
+      'The "Edit" contextual link is shown for the default revision.');
+    $this->assertTrue(strstr($json[$ids[0]], '<li class="entitynodedelete-form"><a href="' . base_path() . 'node/' . $node->id() . '/delete">Delete</a></li>'),
+      'The "Delete" contextual link is shown for the default revision.');
+
     // Confirm that revisions revert properly.
     $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionid() . "/revert", array(), t('Revert'));
     $this->assertRaw(t('@type %title has been reverted back to the revision from %revision-date.',
@@ -106,6 +127,18 @@ function testRevisions() {
     $node = node_revision_load($node->getRevisionId());
     $this->assertFalse($node->isDefaultRevision(), 'Third node revision is not the default one.');
 
+    // Confirm that "Edit" and "Delete" contextual links don't appear for
+    // non-default revision.
+    $ids = array('node_revision::node=' . $node->id() . '&node_revision=' . $node->getRevisionId() . ':');
+    $response = $this->renderContextualLinks($ids, "node/" . $node->id() . '/revisions/' . $node->getRevisionId() . '/view');
+    $json = Json::decode($response);
+    $this->verbose($json[$ids[0]]);
+
+    $this->assertFalse(strstr($json[$ids[0]], '<li class="entitynodeedit-form">'),
+      'The "Edit" contextual link is not shown for a non-default revision.');
+    $this->assertFalse(strstr($json[$ids[0]], '<li class="entitynodedelete-form">'),
+      'The "Delete" contextual link is not shown for a non-default revision.');
+
     // Confirm revisions delete properly.
     $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/delete", array(), t('Delete'));
     $this->assertRaw(t('Revision from %revision-date of @type %title has been deleted.',
@@ -203,4 +236,23 @@ function testNodeRevisionWithoutLogMessage() {
     $node_revision = $node_storage->load($node->id());
     $this->assertTrue(empty($node_revision->revision_log->value), 'After a new node revision is saved with an empty log message, the log message for the node is empty.');
   }
+
+  /**
+   * Get server-rendered contextual links for the given contextual links ids.
+   *
+   * @param array $ids
+   *   An array of contextual link ids.
+   * @param string $current_path
+   *   The Drupal path for the page for which the contextual links are rendered.
+   *
+   * @return string
+   *   The response body.
+   */
+  protected function renderContextualLinks($ids, $current_path) {
+    $post = array();
+    for ($i = 0; $i < count($ids); $i++) {
+      $post['ids[' . $i . ']'] = $ids[$i];
+    }
+    return $this->drupalPost('contextual/render', 'application/json', $post, array('query' => array('destination' => $current_path)));
+  }
 }
