diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php
index 77b96d6..8fa68b0 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php
@@ -29,6 +29,16 @@ class NodeAccessLanguageTest extends NodeTestBase {
     }
   }
 
+  /**
+   * Asserts node_access_grants correctly returns permission IDs
+   */
+  function assertNodeAccessGrants($ops, $node, $account, $langcode = NULL) {
+    foreach ($ops as $op => $result) {
+      $msg = t("node_access returns @result with operation '@op', language code @langcode.", array('@result' => $result ? 'true' : 'false', '@op' => $op, '@langcode' => !empty($langcode) ? "'$langcode'" : 'empty'));
+      $this->assertEqual($result, node_access_grants($op, $account), $msg);
+    }
+  }
+
   function setUp() {
     parent::setUp(array('language', 'node_access_test'));
     // Clear permissions for authenticated users.
@@ -77,4 +87,44 @@ class NodeAccessLanguageTest extends NodeTestBase {
     // Tests that Catalan is not accessible anymore.
     $this->assertNodeAccess(array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE), $node, $web_user, 'ca');
   }
+  /**
+   * Runs tests for node_access_grants function with multiple languages.
+   */
+  function testNodeAccessGrants() {
+    // Add Hungarian and Catalan.
+    $language = (object) array(
+      'langcode' => 'hu',
+    );
+    language_save($language);
+    $language = (object) array(
+      'langcode' => 'ca',
+    );
+    language_save($language);
+
+    // Tests the default access provided for a published Hungarian node.
+    $web_user = $this->drupalCreateUser(array('access content'));
+    $node = $this->drupalCreateNode(array('body' => array('hu' => array(array())), 'langcode' => 'hu'));
+    $this->assertTrue($node->langcode == 'hu', t('Node created as Hungarian.'));
+    $expected_node_access = array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE);
+    $this->assertNodeAccessGrants($expected_node_access, $node, $web_user);
+
+    // Tests that Hungarian provided specifically results in the same.
+    $this->assertNodeAccessGrants($expected_node_access, $node, $web_user, 'hu');
+
+    // There is no specific Catalan version of this node and Croatian is not
+    // even set up on the system in this scenario, so these languages will not
+    // play a role in the node's permissions.
+    $this->assertNodeAccessGrants($expected_node_access, $node, $web_user, 'ca');
+    $this->assertNodeAccessGrants($expected_node_access, $node, $web_user, 'hr');
+
+    // Reset the node access cache and turn on our test node_access() code.
+    drupal_static_reset('node_access');
+    variable_set('node_access_test_secret_catalan', 1);
+
+    // Tests that Hungarian is still accessible.
+    $this->assertNodeAccessGrants($expected_node_access, $node, $web_user, 'hu');
+
+    // Tests that Catalan is not accessible anymore.
+    $this->assertNodeAccessGrants(array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE), $node, $web_user, 'ca');
+  }
 }
diff --git a/core/modules/node/node.api.php b/core/modules/node/node.api.php
index 9719fc0..3dac85f 100644
--- a/core/modules/node/node.api.php
+++ b/core/modules/node/node.api.php
@@ -233,10 +233,13 @@ function hook_node_grants($account, $op) {
  *   of this gid within this realm can edit this node.
  * - 'grant_delete': If set to 1 a user that has been identified as a member
  *   of this gid within this realm can delete this node.
+ * - 'langcode': Optional key. The language code of the grant version. This
+ *   value is set automatically from the $node parameter during database
+ *   storage.
  *
  *
- * When an implementation is interested in a node but want to deny access to
- * everyone, it may return a "deny all" grant:
+ * When an implementation is interested in a node in Catalan language, but want
+ * to deny access to everyone, it may return a "deny all" grant:
  *
  * @code
  * $grants[] = array(
@@ -246,6 +249,7 @@ function hook_node_grants($account, $op) {
  *   'grant_update' => 0,
  *   'grant_delete' => 0,
  *   'priority' => 1,
+ *   'langcode' => 'ca'
  * );
  * @endcode
  *
@@ -269,7 +273,7 @@ function hook_node_access_records(Drupal\node\Node $node) {
   // treated just like any other node and we completely ignore it.
   if ($node->private) {
     $grants = array();
-    // Only published nodes should be viewable to all users. If we allow access
+    // Only published Catalan nodes should be viewable to all users. If we allow access
     // blindly here, then all users could view an unpublished node.
     if ($node->status) {
       $grants[] = array(
@@ -278,6 +282,7 @@ function hook_node_access_records(Drupal\node\Node $node) {
         'grant_view' => 1,
         'grant_update' => 0,
         'grant_delete' => 0,
+        'langcode' => 'ca'
       );
     }
     // For the example_author array, the GID is equivalent to a UID, which
@@ -290,6 +295,7 @@ function hook_node_access_records(Drupal\node\Node $node) {
       'grant_view' => 1,
       'grant_update' => 1,
       'grant_delete' => 1,
+      'langcode' => 'ca'
     );
 
     return $grants;
diff --git a/core/modules/node/node.install b/core/modules/node/node.install
index 7382320..157a3ed 100644
--- a/core/modules/node/node.install
+++ b/core/modules/node/node.install
@@ -141,6 +141,13 @@ function node_schema() {
         'not null' => TRUE,
         'default' => 0,
       ),
+      'langcode' => array(
+        'description' => 'The {language}.langcode of this node.',
+        'type' => 'varchar',
+        'length' => 12,
+        'not null' => TRUE,
+        'default' => '',
+      ),
       'gid' => array(
         'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.",
         'type' => 'int',
@@ -568,6 +575,21 @@ function node_update_8003() {
 }
 
 /**
+ * Add language.langcode field to node_access table.
+ */
+function node_update_8004() {
+  // Add the langcode field.
+  $langcode_field = array(
+    'type' => 'varchar',
+    'length' => 12,
+    'not null' => TRUE,
+    'default' => '',
+    'description' => 'The {language}.langcode of this node.',
+  );
+  db_add_field('node_access', 'langcode', $langcode_field);
+}
+
+/**
  * @} End of "addtogroup updates-7.x-to-8.x"
  * The next series of updates should start at 9000.
  */
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 3db5bbd..6cf1ee8 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -3426,7 +3426,9 @@ function node_access_acquire_grants(Node $node, $delete = TRUE) {
  *   nid.
  * @param $grants
  *   A list of grants to write. Each grant is an array that must contain the
- *   following keys: realm, gid, grant_view, grant_update, grant_delete.
+ *   following keys: realm, gid, grant_view, grant_update, grant_delete and
+ *   langcode is an optional key which is set automatically from $node
+ *   parameter.
  *   The realm is specified by a particular module; the gid is as well, and
  *   is a module-defined id to define grant privileges. each grant_* field
  *   is a boolean value.
@@ -3448,7 +3450,7 @@ function _node_access_write_grants(Node $node, $grants, $realm = NULL, $delete =
 
   // Only perform work when node_access modules are active.
   if (!empty($grants) && count(module_implements('node_grants'))) {
-    $query = db_insert('node_access')->fields(array('nid', 'realm', 'gid', 'grant_view', 'grant_update', 'grant_delete'));
+    $query = db_insert('node_access')->fields(array('nid', 'langcode', 'realm', 'gid', 'grant_view', 'grant_update', 'grant_delete'));
     foreach ($grants as $grant) {
       if ($realm && $realm != $grant['realm']) {
         continue;
@@ -3456,6 +3458,9 @@ function _node_access_write_grants(Node $node, $grants, $realm = NULL, $delete =
       // Only write grants; denies are implicit.
       if ($grant['grant_view'] || $grant['grant_update'] || $grant['grant_delete']) {
         $grant['nid'] = $node->nid;
+        if (!isset($grant['langcode'])) {
+          $grant['langcode'] = $node->langcode;
+        }
         $query->values($grant);
       }
     }
