diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index a54fc0a..a12976b 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -904,6 +904,10 @@ function node_node_access(NodeInterface $node, $op, $account) {
   $type = $node->bundle();
 
   switch ($op) {
+    case 'view':
+      if (!$node->isPublished()) {
+        return AccessResult::allowedIfHasPermissions($account, array('view any unpublished content', 'view unpublished ' . $type . ' content'), 'OR');
+      }
     case 'create':
       return AccessResult::allowedIfHasPermission($account, 'create ' . $type . ' content');
 
diff --git a/core/modules/node/node.permissions.yml b/core/modules/node/node.permissions.yml
index f852db7..ff7cae3 100644
--- a/core/modules/node/node.permissions.yml
+++ b/core/modules/node/node.permissions.yml
@@ -17,6 +17,8 @@ access content:
   title: 'View published content'
 view own unpublished content:
   title: 'View own unpublished content'
+view any unpublished content:
+  title: 'View any unpublished content'
 view all revisions:
   title: 'View all revisions'
 revert all revisions:
diff --git a/core/modules/node/src/NodePermissions.php b/core/modules/node/src/NodePermissions.php
index fd28110..94b426c 100644
--- a/core/modules/node/src/NodePermissions.php
+++ b/core/modules/node/src/NodePermissions.php
@@ -65,6 +65,9 @@ protected function buildPermissions(NodeType $type) {
       "delete any $type_id content" => array(
         'title' => $this->t('%type_name: Delete any content', $type_params),
       ),
+      "view unpublished $type_id content" => array(
+        'title' => $this->t('%type_name: View unpublished', $type_params),
+      ),
       "view $type_id revisions" => array(
         'title' => $this->t('%type_name: View revisions', $type_params),
       ),
diff --git a/core/modules/node/src/Tests/NodeAccessTest.php b/core/modules/node/src/Tests/NodeAccessTest.php
index 4decd66..5c83b10 100644
--- a/core/modules/node/src/Tests/NodeAccessTest.php
+++ b/core/modules/node/src/Tests/NodeAccessTest.php
@@ -55,23 +55,37 @@ function testNodeAccess() {
     $this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE), $node4, $web_user4);
     $this->assertNodeAccess(array('view' => FALSE), $node4, $web_user5);
 
+    // Ensures user with 'view any unpublished content' can do so.
+    $web_user6 = $this->drupalCreateUser(array('access content', 'view any unpublished content'));
+    $this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE), $node4, $web_user6);
+
+    // Ensures the more granular view unpublished permissions are respected.
+    $web_user7 = $this->drupalCreateUser(array('access content', 'view unpublished page content'));
+    $web_user8 = $this->drupalCreateUser(array('access content', 'view unpublished article content'));
+    $node5 = $this->drupalCreateNode(array('type' => 'page', 'status' => 0));
+    $node6 = $this->drupalCreateNode(array('type' => 'article', 'status' => 0));
+    $this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE), $node5, $web_user7);
+    $this->assertNodeAccess(array('view' => FALSE, 'update' => FALSE), $node5, $web_user8);
+    $this->assertNodeAccess(array('view' => FALSE, 'update' => FALSE), $node6, $web_user7);
+    $this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE), $node6, $web_user8);
+
     // Tests the default access provided for a published node.
-    $node5 = $this->drupalCreateNode();
-    $this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE), $node5, $web_user3);
+    $node7 = $this->drupalCreateNode();
+    $this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE), $node7, $web_user3);
 
     // Tests the "edit any BUNDLE" and "delete any BUNDLE" permissions.
-    $web_user6 = $this->drupalCreateUser(array('access content', 'edit any page content', 'delete any page content'));
-    $node6 = $this->drupalCreateNode(array('type' => 'page'));
-    $this->assertNodeAccess(array('view' => TRUE, 'update' => TRUE, 'delete' => TRUE), $node6, $web_user6);
+    $web_user9 = $this->drupalCreateUser(array('access content', 'edit any page content', 'delete any page content'));
+    $node8 = $this->drupalCreateNode(array('type' => 'page'));
+    $this->assertNodeAccess(array('view' => TRUE, 'update' => TRUE, 'delete' => TRUE), $node8, $web_user9);
 
     // Tests the "edit own BUNDLE" and "delete own BUNDLE" permission.
-    $web_user7 = $this->drupalCreateUser(array('access content', 'edit own page content', 'delete own page content'));
+    $web_user10 = $this->drupalCreateUser(array('access content', 'edit own page content', 'delete own page content'));
     // User should not be able to edit or delete nodes they do not own.
-    $this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE), $node6, $web_user7);
+    $this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE), $node8, $web_user10);
 
     // User should be able to edit or delete nodes they own.
-    $node7 = $this->drupalCreateNode(array('type' => 'page', 'uid' => $web_user7->id()));
-    $this->assertNodeAccess(array('view' => TRUE, 'update' => TRUE, 'delete' => TRUE), $node7, $web_user7);
+    $node9 = $this->drupalCreateNode(array('type' => 'page', 'uid' => $web_user10->id()));
+    $this->assertNodeAccess(array('view' => TRUE, 'update' => TRUE, 'delete' => TRUE), $node9, $web_user10);
   }
 
 }
