diff --git a/core/modules/node/lib/Drupal/node/NodeAccessController.php b/core/modules/node/lib/Drupal/node/NodeAccessController.php
index 9b5a403..5239e16 100644
--- a/core/modules/node/lib/Drupal/node/NodeAccessController.php
+++ b/core/modules/node/lib/Drupal/node/NodeAccessController.php
@@ -91,9 +91,13 @@ protected function checkAccess(EntityInterface $node, $operation, $langcode, Acc
     $status = $node->getTranslation($langcode)->isPublished();
     $uid = $node->getTranslation($langcode)->getAuthorId();
 
+    // Ensure users with permissions to view any unpublished content can do so.
+    if ($operation == 'view' && !$status && user_access('view any unpublished content', $account)) {
+      return TRUE;
+    }
+
     // Check if authors can view their own unpublished nodes.
     if ($operation === 'view' && !$status && user_access('view own unpublished content', $account)) {
-
       if ($account->id() != 0 && $account->id() == $uid) {
         return TRUE;
       }
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessTest.php
index 66448d0..ee1d2b6 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessTest.php
@@ -60,9 +60,23 @@ 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'));
+    $web_user8 = $this->drupalCreateUser(array('access content', 'view unpublished page content'));
+    $web_user9 = $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_user8);
+    $this->assertNodeAccess(array('view' => FALSE, 'update' => FALSE), $node5, $web_user9);
+    $this->assertNodeAccess(array('view' => FALSE, 'update' => FALSE), $node6, $web_user8);
+    $this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE), $node6, $web_user9);
+
     // 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);
   }
-
 }
diff --git a/core/modules/node/node.admin.inc b/core/modules/node/node.admin.inc
index 03387f8..dce552b 100644
--- a/core/modules/node/node.admin.inc
+++ b/core/modules/node/node.admin.inc
@@ -202,7 +202,9 @@ function node_admin_nodes() {
     ->extend('Drupal\Core\Database\Query\PagerSelectExtender')
     ->extend('Drupal\Core\Database\Query\TableSortExtender');
 
-  if (!user_access('bypass node access')) {
+  // If the user is allowed to bypass node access or if the user is allowed to
+  // view all unpublished content, then we don't need to add any extra checks.
+  if (!user_access('bypass node access') && !user_access('view any unpublished content')) {
     // If the user is able to view their own unpublished nodes, allow them
     // to see these in addition to published nodes. Check that they actually
     // have some unpublished nodes to view before adding the condition.
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index e1d2b63..5efe7b3 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -768,6 +768,9 @@ function node_permission() {
     'view own unpublished content' => array(
       'title' => t('View own unpublished content'),
     ),
+    'view any unpublished content' => array(
+      'title' => t('View any unpublished content'),
+    ),
     'view all revisions' => array(
       'title' => t('View all revisions'),
     ),
@@ -1136,7 +1139,9 @@ function node_revision_list(EntityInterface $node) {
 function node_get_recent($number = 10) {
   $query = db_select('node_field_data', 'n');
 
-  if (!user_access('bypass node access')) {
+  // If the user is allowed to bypass node access or if the user is allowed to
+  // view all unpublished content, then we don't need to add any extra checks.
+  if (!user_access('bypass node access') && !user_access('view any unpublished content')) {
     // If the user is able to view their own unpublished nodes, allow them
     // to see these in addition to published nodes. Check that they actually
     // have some unpublished nodes to view before adding the condition.
@@ -1644,6 +1649,10 @@ function node_node_access($node, $op, $account) {
 
   $configured_types = node_permissions_get_configured_types();
   if (isset($configured_types[$type])) {
+    if ($op == 'view' && user_access('view unpublished ' . $type . ' content', $account)) {
+      return NODE_ACCESS_ALLOW;
+    }
+
     if ($op == 'create' && user_access('create ' . $type . ' content', $account)) {
       return NODE_ACCESS_ALLOW;
     }
@@ -1676,6 +1685,9 @@ function node_node_access($node, $op, $account) {
 function node_list_permissions($type) {
   // Build standard list of node permissions for this type.
   $perms = array(
+    "view unpublished $type->type content" => array(
+      'title' => t('%type_name: View unpublished', array('%type_name' => $type->name)),
+    ),
     "create $type->type content" => array(
       'title' => t('%type_name: Create new content', array('%type_name' => $type->name)),
     ),
