diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index fe30114..2b3885e 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -865,21 +865,11 @@ function entity_page_access(EntityInterface $entity, $operation = 'view') {
  *   The entity type.
  * @param string $bundle
  *   (optional) The bundle of the entity. Required if the entity supports
- *   bundles, defaults to the entity type otherwise.
+ *   bundles, defaults to NULL otherwise.
  *
  * @return bool
  *   TRUE if the access is granted. FALSE if access is denied.
  */
 function entity_page_create_access($entity_type, $bundle = NULL) {
-  $definition = Drupal::entityManager()->getDefinition($entity_type);
-
-  // Pass in the entity bundle if given and required.
-  $values = array();
-  if ($bundle && isset($definition['entity_keys']['bundle'])) {
-    $values[$definition['entity_keys']['bundle']] = $bundle;
-  }
-  $entity = Drupal::entityManager()
-    ->getStorageController($entity_type)
-    ->create($values);
-  return $entity->access('create');
+  return Drupal::entityManager()->getAccessController($entity_type)->createAccess($bundle);
 }
diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php
index 33a62ce..ec05c1a 100644
--- a/core/lib/Drupal/Core/Entity/Entity.php
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -273,6 +273,11 @@ public function getIterator() {
    * Implements \Drupal\Core\TypedData\AccessibleInterface::access().
    */
   public function access($operation = 'view', AccountInterface $account = NULL) {
+    if ($operation == 'create') {
+      return \Drupal::entityManager()
+        ->getAccessController($this->entityType)
+        ->createAccess($this->bundle(), $account);
+    }
     return \Drupal::entityManager()
       ->getAccessController($this->entityType)
       ->access($this, $operation, Language::LANGCODE_DEFAULT, $account);
diff --git a/core/lib/Drupal/Core/Entity/EntityAccessController.php b/core/lib/Drupal/Core/Entity/EntityAccessController.php
index a328443..5e24912 100644
--- a/core/lib/Drupal/Core/Entity/EntityAccessController.php
+++ b/core/lib/Drupal/Core/Entity/EntityAccessController.php
@@ -23,14 +23,27 @@ class EntityAccessController implements EntityAccessControllerInterface {
   protected $accessCache = array();
 
   /**
+   * The entity type of the access controller instance.
+   *
+   * @var string
+   */
+  protected $entityType;
+
+  /**
+   * @param string $entity_type
+   *   The entity type of the access controller instance.
+   */
+  public function __construct($entity_type) {
+    $this->entity_type = $entity_type;
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function access(EntityInterface $entity, $operation, $langcode = Language::LANGCODE_DEFAULT, AccountInterface $account = NULL) {
-    if (!$account) {
-      $account = $GLOBALS['user'];
-    }
+    $account = $this->prepareUser($account);
 
-    if (($access = $this->getCache($entity, $operation, $langcode, $account)) !== NULL) {
+    if (($access = $this->getCache($entity->uuid(), $operation, $langcode, $account)) !== NULL) {
       // Cache hit, no work necessary.
       return $access;
     }
@@ -45,17 +58,36 @@ public function access(EntityInterface $entity, $operation, $langcode = Language
     // - At least one module says to grant access.
     $access = module_invoke_all($entity->entityType() . '_access', $entity->getBCEntity(), $operation, $account, $langcode);
 
+    if (($return = $this->processAccessHookResults($access)) === NULL) {
+      // No module had an opinion about the access, so let's the access
+      // controller check create access.
+      $return = (bool) $this->checkAccess($entity, $operation, $langcode, $account);
+    }
+    return $this->setCache($return, $entity->uuid(), $operation, $langcode, $account);
+  }
+
+  /**
+   * We grant access to the entity if both of these conditions are met:
+   * - No modules say to deny access.
+   * - At least one module says to grant access.
+   *
+   * @param array $access
+   *   An array of access results of the fired access hook.
+   *
+   * @return bool|NULL
+   *   Returns FALSE if access should be denied, TRUE if access should be
+   *   granted and NULL if no module denied access.
+   */
+  protected function processAccessHookResults(array $access) {
     if (in_array(FALSE, $access, TRUE)) {
-      $return = FALSE;
+      return FALSE;
     }
     elseif (in_array(TRUE, $access, TRUE)) {
-      $return = TRUE;
+      return TRUE;
     }
     else {
-      // No result from hook, so entity checks are done.
-      $return = (bool) $this->checkAccess($entity, $operation, $langcode, $account);
+      return;
     }
-    return $this->setCache($return, $entity, $operation, $langcode, $account);
   }
 
   /**
@@ -85,8 +117,9 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
   /**
    * Tries to retrieve a previously cached access value from the static cache.
    *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   The entity for which to check 'create' access.
+   * @param string $cid
+   *   Unique string identifier for the entity/operation, for example the
+   *   entity UUID or a custom string.
    * @param string $operation
    *   The entity operation. Usually one of 'view', 'update', 'create' or
    *   'delete'.
@@ -100,13 +133,12 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
    *   is no record for the given user, operation, langcode and entity in the
    *   cache.
    */
-  protected function getCache(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
+  protected function getCache($cid, $operation, $langcode, AccountInterface $account) {
     $uid = $account ? $account->id() : 0;
-    $uuid = $entity->uuid();
 
     // Return from cache if a value has been set for it previously.
-    if (isset($this->accessCache[$uid][$uuid][$langcode][$operation])) {
-      return $this->accessCache[$uid][$uuid][$langcode][$operation];
+    if (isset($this->accessCache[$uid][$cid][$langcode][$operation])) {
+      return $this->accessCache[$uid][$cid][$langcode][$operation];
     }
   }
 
@@ -115,8 +147,9 @@ protected function getCache(EntityInterface $entity, $operation, $langcode, Acco
    *
    * @param bool $access
    *   TRUE if the user has access, FALSE otherwise.
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   The entity for which to check 'create' access.
+   * @param string $cid
+   *   Unique string identifier for the entity/operation, for example the
+   *   entity UUID or a custom string.
    * @param string $operation
    *   The entity operation. Usually one of 'view', 'update', 'create' or
    *   'delete'.
@@ -128,12 +161,11 @@ protected function getCache(EntityInterface $entity, $operation, $langcode, Acco
    * @return bool
    *   TRUE if access was granted, FALSE otherwise.
    */
-  protected function setCache($access, EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
+  protected function setCache($access, $cid, $operation, $langcode, AccountInterface $account) {
     $uid = $account ? $account->id() : 0;
-    $uuid = $entity->uuid();
 
     // Save the given value in the static cache and directly return it.
-    return $this->accessCache[$uid][$uuid][$langcode][$operation] = (bool) $access;
+    return $this->accessCache[$uid][$cid][$langcode][$operation] = (bool) $access;
   }
 
   /**
@@ -143,4 +175,75 @@ public function resetCache() {
     $this->accessCache = array();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function createAccess($entity_bundle = NULL, AccountInterface $account = NULL, array $context = array()) {
+    $account = $this->prepareUser($account);
+    $context += array(
+      'langcode' => Language::LANGCODE_DEFAULT,
+    );
+
+    $cid = $entity_bundle ? 'create:' . $entity_bundle : 'create';
+    if (($access = $this->getCache($cid, 'create', $context['langcode'], $account)) !== NULL) {
+      // Cache hit, no work necessary.
+      return $access;
+    }
+
+    // Invoke hook_entity_access(), hook results take precedence over overridden
+    // implementations of EntityAccessController::checkAccess(). Entities
+    // that have checks that need to be done before the hook is invoked should
+    // do so by overridding this method.
+
+    // We grant access to the entity if both of these conditions are met:
+    // - No modules say to deny access.
+    // - At least one module says to grant access.
+    $access = module_invoke_all($this->entity_type . '_create_access', $account, $context['langcode']);
+
+    if (($return = $this->processAccessHookResults($access)) === NULL) {
+      // No module had an opinion about the access, so let's the access
+      // controller check create access.
+      $return = (bool) $this->checkCreateAccess($account, $context, $entity_bundle);
+    }
+    return $this->setCache($return, $cid, 'create', $context['langcode'], $account);
+  }
+
+  /**
+   * Performs create access checks.
+   *
+   * This method is supposed to be overwritten by extending classes that
+   * do their own custom access checking.
+   *
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The user for which to check access.
+   * @param array $context
+   *   An array of key-value pairs to pass additional context when needed.
+   * @param string|null $entity_bundle
+   *   (optional) The bundle of the entity. Required if the entity supports
+   *   bundles, defaults to NULL otherwise.
+   *
+   * @return bool|null
+   *   TRUE if access was granted, FALSE if access was denied and NULL if access
+   *   could not be determined.
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return NULL;
+  }
+
+  /**
+   * Loads the current account object, if it does not exist yet.
+   *
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The account interface instance.
+   *
+   * @return \Drupal\Core\Session\AccountInterface
+   *   Returns the current account object.
+   */
+  protected function prepareUser(AccountInterface $account = NULL) {
+    if (!$account) {
+      $account = $GLOBALS['user'];
+    }
+    return $account;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Entity/EntityAccessControllerInterface.php b/core/lib/Drupal/Core/Entity/EntityAccessControllerInterface.php
index f7b4348..c0296dd 100644
--- a/core/lib/Drupal/Core/Entity/EntityAccessControllerInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityAccessControllerInterface.php
@@ -18,11 +18,14 @@
   /**
    * Checks access to an operation on a given entity or entity translation.
    *
+   * Use \Drupal\Core\Entity\EntityAccessControllerInterface::createAccess()
+   * to check access to create an entity.
+   *
    * @param \Drupal\Core\Entity\EntityInterface $entity
    *   The entity for which to check access.
    * @param string $operation
    *   The operation access should be checked for.
-   *   Usually one of "view", "create", "update" or "delete".
+   *   Usually one of "view", "update" or "delete".
    * @param string $langcode
    *   (optional) The language code for which to check access. Defaults to
    *   Language::LANGCODE_DEFAULT.
@@ -36,6 +39,21 @@
   public function access(EntityInterface $entity, $operation, $langcode = Language::LANGCODE_DEFAULT, AccountInterface $account = NULL);
 
   /**
+   * Checks access to create an entity.
+   *
+   * @param string $entity_bundle
+   *   (optional) The bundle of the entity. Required if the entity supports
+   *   bundles, defaults to NULL otherwise.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   (optional) The user session for which to check access, or NULL to check
+   *   access for the current user. Defaults to NULL.
+   * @param array $context
+   *   (optional) An array of key-value pairs to pass additional context when
+   *   needed.
+   */
+  public function createAccess($entity_bundle = NULL, AccountInterface $account = NULL, array $context = array());
+
+    /**
    * Clears all cached access checks.
    */
   public function resetCache();
diff --git a/core/lib/Drupal/Core/Entity/EntityNG.php b/core/lib/Drupal/Core/Entity/EntityNG.php
index a6768e8..62b5bfb 100644
--- a/core/lib/Drupal/Core/Entity/EntityNG.php
+++ b/core/lib/Drupal/Core/Entity/EntityNG.php
@@ -413,6 +413,11 @@ public function isEmpty() {
    * {@inheritdoc}
    */
   public function access($operation = 'view', AccountInterface $account = NULL) {
+    if ($operation == 'create') {
+      return \Drupal::entityManager()
+        ->getAccessController($this->entityType)
+        ->createAccess($this->bundle(), $account);
+    }
     return \Drupal::entityManager()
       ->getAccessController($this->entityType)
       ->access($this, $operation, $this->activeLangcode, $account);
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockAccessController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockAccessController.php
index 8ac282a..9990a2e 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockAccessController.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockAccessController.php
@@ -23,9 +23,16 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
     if ($operation === 'view') {
       return TRUE;
     }
-    elseif (in_array($operation, array('create', 'update', 'delete'))) {
+    elseif (in_array($operation, array('update', 'delete'))) {
       return user_access('administer blocks', $account);
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return user_access('administer blocks', $account);
+  }
+
 }
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeAccessController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeAccessController.php
index 3aa95ce..95b74ac 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeAccessController.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeAccessController.php
@@ -23,9 +23,16 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
     if ($operation === 'view') {
       return TRUE;
     }
-    elseif (in_array($operation, array('create', 'update', 'delete'))) {
+    elseif (in_array($operation, array('update', 'delete'))) {
       return user_access('administer blocks', $account);
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return user_access('administer blocks', $account);
+  }
+
 }
diff --git a/core/modules/comment/lib/Drupal/comment/CommentAccessController.php b/core/modules/comment/lib/Drupal/comment/CommentAccessController.php
index da728d5..98e03e1 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentAccessController.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentAccessController.php
@@ -27,10 +27,6 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
         return user_access('access comments', $account);
         break;
 
-      case 'create':
-        return user_access('post comments', $account);
-        break;
-
       case 'update':
         return ($account->id() && $account->id() == $entity->uid->value && $entity->status->value == COMMENT_PUBLISHED && user_access('edit own comments', $account)) || user_access('administer comments', $account);
         break;
@@ -45,4 +41,11 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return user_access('post comments', $account);
+  }
+
 }
diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestAccessController.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestAccessController.php
index cde6f41..f084453 100644
--- a/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestAccessController.php
+++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestAccessController.php
@@ -24,4 +24,11 @@ public function access(EntityInterface $entity, $operation, $langcode = Language
     return TRUE;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return TRUE;
+  }
+
 }
diff --git a/core/modules/filter/lib/Drupal/filter/FilterFormatAccessController.php b/core/modules/filter/lib/Drupal/filter/FilterFormatAccessController.php
index 133c309..1242b94 100644
--- a/core/modules/filter/lib/Drupal/filter/FilterFormatAccessController.php
+++ b/core/modules/filter/lib/Drupal/filter/FilterFormatAccessController.php
@@ -36,4 +36,11 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
     return !empty($permission) && user_access($permission, $account);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return user_access('administer filters', $account);
+  }
+
 }
diff --git a/core/modules/menu/lib/Drupal/menu/MenuAccessController.php b/core/modules/menu/lib/Drupal/menu/MenuAccessController.php
index 4cb2962..b7128c0 100644
--- a/core/modules/menu/lib/Drupal/menu/MenuAccessController.php
+++ b/core/modules/menu/lib/Drupal/menu/MenuAccessController.php
@@ -31,9 +31,16 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
       }
     }
 
-    if (in_array($operation, array('create', 'update', 'delete'))) {
+    if (in_array($operation, array('update', 'delete'))) {
       return user_access('administer menu', $account);
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return user_access('administer menu', $account);
+  }
+
 }
diff --git a/core/modules/node/lib/Drupal/node/NodeAccessController.php b/core/modules/node/lib/Drupal/node/NodeAccessController.php
index c0106a7..2556d76 100644
--- a/core/modules/node/lib/Drupal/node/NodeAccessController.php
+++ b/core/modules/node/lib/Drupal/node/NodeAccessController.php
@@ -41,12 +41,17 @@ class NodeAccessController extends EntityAccessController implements NodeAccessC
   /**
    * Constructs a NodeAccessController object.
    *
+   * @param string $entity_type
+   *   The entity type of the access controller instance.
    * @param \Drupal\node\NodeGrantDatabaseStorageInterface $grant_storage
    *   The node grant storage.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler to invoke the alter hook with.
    */
-  public function __construct(NodeGrantDatabaseStorageInterface $grant_storage, ModuleHandlerInterface $module_handler) {
-     $this->grantStorage = $grant_storage;
-     $this->moduleHandler = $module_handler;
+  public function __construct($entity_type, NodeGrantDatabaseStorageInterface $grant_storage, ModuleHandlerInterface $module_handler) {
+    parent::__construct($entity_type);
+    $this->grantStorage = $grant_storage;
+    $this->moduleHandler = $module_handler;
   }
 
   /**
@@ -54,6 +59,7 @@ public function __construct(NodeGrantDatabaseStorageInterface $grant_storage, Mo
    */
   public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) {
     return new static(
+      $entity_type,
       $container->get('node.grant_storage'),
       $container->get('module_handler')
     );
@@ -76,6 +82,22 @@ public function access(EntityInterface $entity, $operation, $langcode = Language
   /**
    * {@inheritdoc}
    */
+  public function createAccess($entity_bundle = NULL, AccountInterface $account = NULL, array $context = array()) {
+    $account = $this->prepareUser($account);
+
+    if (user_access('bypass node access', $account)) {
+      return TRUE;
+    }
+    if (!user_access('access content', $account)) {
+      return FALSE;
+    }
+
+    return parent::createAccess($entity_bundle, $account, $context);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   protected function checkAccess(EntityInterface $node, $operation, $langcode, AccountInterface $account) {
     // Fetch information from the node object if possible.
     $status = isset($node->status) ? $node->status : NULL;
@@ -110,6 +132,16 @@ protected function checkAccess(EntityInterface $node, $operation, $langcode, Acc
   /**
    * {@inheritdoc}
    */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    $configured_types = node_permissions_get_configured_types();
+    if (isset($configured_types[$entity_bundle])) {
+      return user_access('create ' . $entity_bundle . ' content', $account);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function acquireGrants(NodeInterface $node) {
     $grants = $this->moduleHandler->invokeAll('node_access_records', array($node));
     // Let modules alter the grants.
diff --git a/core/modules/node/lib/Drupal/node/NodeTypeAccessController.php b/core/modules/node/lib/Drupal/node/NodeTypeAccessController.php
index 40327e3..55238a6 100644
--- a/core/modules/node/lib/Drupal/node/NodeTypeAccessController.php
+++ b/core/modules/node/lib/Drupal/node/NodeTypeAccessController.php
@@ -28,4 +28,11 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
     return user_access('administer content types', $account);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return user_access('administer content types', $account);
+  }
+
 }
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 293c64e..979edc2 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -2028,37 +2028,43 @@ function node_form_system_themes_admin_form_submit($form, &$form_state) {
  * @see node_menu()
  */
 function node_access($op, $node, $account = NULL, $langcode = NULL) {
-  if (!$node instanceof EntityInterface) {
-    $node = entity_create('node', array('type' => $node));
-  }
-  elseif ($node instanceof NodeTypeInterface) {
-    $node = entity_create('node', array('type' => $node->id()));
-  }
-
-  // If no language code was provided, default to the node's langcode.
-  if (empty($langcode)) {
-    $langcode = $node->language()->id;
-    // If the Language module is enabled, try to use the language from content
-    // negotiation.
-    if (module_exists('language')) {
-      // Load languages the node exists in.
-      $node_translations = $node->getTranslationLanguages();
-      // Load the language from content negotiation.
-      $content_negotiation_langcode = language(Language::TYPE_CONTENT)->id;
-      // If there is a translation available, use it.
-      if (isset($node_translations[$content_negotiation_langcode])) {
-        $langcode = $content_negotiation_langcode;
+  $access_controller = Drupal::entityManager()->getAccessController('node');
+
+  if ($op == 'create') {
+    if (!$node instanceof EntityInterface) {
+      $bundle = $node;
+    }
+    elseif ($node instanceof NodeTypeInterface) {
+      $bundle = $node->id();
+    }
+    else {
+      $bundle = $node->bundle();
+    }
+  }
+  else {
+    // If no language code was provided, default to the node's langcode.
+    if (empty($langcode)) {
+      $langcode = $node->langcode;
+      // If the Language module is enabled, try to use the language from content
+      // negotiation.
+      if (module_exists('language')) {
+        // Load languages the node exists in.
+        $node_translations = $node->getTranslationLanguages();
+        // Load the language from content negotiation.
+        $content_negotiation_langcode = language(Language::TYPE_CONTENT)->id;
+        // If there is a translation available, use it.
+        if (isset($node_translations[$content_negotiation_langcode])) {
+          $langcode = $content_negotiation_langcode;
+        }
       }
     }
   }
-
-  // Make sure that if an account is passed, that it is a fully loaded user
-  // object.
-  if ($account && !($account instanceof UserInterface)) {
-    $account = user_load($account->id());
+  if ($op == 'create') {
+    return $access_controller->createAccess($bundle, $account, array('langcode' => $langcode));
+  }
+  else {
+    return $access_controller->access($node, $op, $langcode, $account);
   }
-
-  return Drupal::entityManager()->getAccessController('node')->access($node, $op, $langcode, $account);
 }
 
 /**
diff --git a/core/modules/picture/lib/Drupal/picture/PictureMappingAccessController.php b/core/modules/picture/lib/Drupal/picture/PictureMappingAccessController.php
index 5ee0ade..2696100 100644
--- a/core/modules/picture/lib/Drupal/picture/PictureMappingAccessController.php
+++ b/core/modules/picture/lib/Drupal/picture/PictureMappingAccessController.php
@@ -23,9 +23,16 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
     if ($operation === 'view') {
       return TRUE;
     }
-    elseif (in_array($operation, array('create', 'update', 'delete'))) {
+    elseif (in_array($operation, array('update', 'delete'))) {
       return user_access('administer pictures', $account);
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return user_access('administer pictures', $account);
+  }
+
 }
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestAccessController.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestAccessController.php
index c2b5594..034caa3 100644
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestAccessController.php
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestAccessController.php
@@ -27,9 +27,16 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
       }
       return user_access('view test entity', $account);
     }
-    elseif (in_array($operation, array('create', 'update', 'delete'))) {
+    elseif (in_array($operation, array('update', 'delete'))) {
       return user_access('administer entity_test content', $account);
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return user_access('administer entity_test content', $account);
+  }
+
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermAccessController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermAccessController.php
index d562e84..d945ef5 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermAccessController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermAccessController.php
@@ -27,10 +27,6 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
         return user_access('access content', $account);
         break;
 
-      case 'create':
-        return user_access('administer taxonomy', $account);
-        break;
-
       case 'update':
         return user_access("edit terms in {$entity->bundle()}", $account) || user_access('administer taxonomy', $account);
         break;
@@ -41,4 +37,11 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return user_access('administer taxonomy', $account);
+  }
+
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyAccessController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyAccessController.php
index 0750593..ac5ebe9 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyAccessController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyAccessController.php
@@ -25,4 +25,11 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
     return user_access('administer taxonomy', $account);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return user_access('administer taxonomy', $account);
+  }
+
 }
diff --git a/core/modules/translation/translation.module b/core/modules/translation/translation.module
index 993cf13..562f0b2 100644
--- a/core/modules/translation/translation.module
+++ b/core/modules/translation/translation.module
@@ -121,14 +121,14 @@ function translation_permission() {
 }
 
 /**
- * Implements hook_node_access().
+ * Implements hook_node_create_access().
  */
-function translation_node_access($node, $op, $account, $langcode) {
+function translation_node_create_access($account) {
   $query = Drupal::request()->query;
   $translation = $query->get('translation');
   $target = $query->get('target');
   $request_has_translation_arg = !empty($translation) && !empty($target) && is_numeric($translation);
-  if ($op == 'create' && $request_has_translation_arg) {
+  if ($request_has_translation_arg) {
     $source_node = node_load($translation);
     if (empty($source_node) || !translation_user_can_translate_node($source_node, $account)){
       return NODE_ACCESS_DENY;
diff --git a/core/modules/user/lib/Drupal/user/RoleAccessController.php b/core/modules/user/lib/Drupal/user/RoleAccessController.php
index 13afa61..e98c540 100644
--- a/core/modules/user/lib/Drupal/user/RoleAccessController.php
+++ b/core/modules/user/lib/Drupal/user/RoleAccessController.php
@@ -31,4 +31,11 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return user_access('administer permissions', $account);
+  }
+
 }
diff --git a/core/modules/user/lib/Drupal/user/UserAccessController.php b/core/modules/user/lib/Drupal/user/UserAccessController.php
index fd46efa..e6f6ed6 100644
--- a/core/modules/user/lib/Drupal/user/UserAccessController.php
+++ b/core/modules/user/lib/Drupal/user/UserAccessController.php
@@ -25,10 +25,6 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
         return $this->viewAccess($entity, $langcode, $account);
         break;
 
-      case 'create':
-        return user_access('administer users', $account);
-        break;
-
       case 'update':
         // Users can always edit their own account. Users with the 'administer
         // users' permission can edit any account except the anonymous account.
@@ -45,6 +41,13 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
   }
 
   /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return user_access('administer users', $account);
+  }
+
+  /**
    * Check view access.
    *
    * See EntityAccessControllerInterface::view() for parameters.
diff --git a/core/modules/views/lib/Drupal/views/ViewAccessController.php b/core/modules/views/lib/Drupal/views/ViewAccessController.php
index a4aaae6..80ad8a9 100644
--- a/core/modules/views/lib/Drupal/views/ViewAccessController.php
+++ b/core/modules/views/lib/Drupal/views/ViewAccessController.php
@@ -24,4 +24,11 @@ public function access(EntityInterface $entity, $operation, $langcode = Language
     return $operation == 'view' || user_access('administer views', $account);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return user_access('administer views', $account);
+  }
+
 }
