diff --git a/core/core.services.yml b/core/core.services.yml
index 2e186ae..78398b8 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -302,6 +302,10 @@ services:
     class: Drupal\Core\Access\DefaultAccessCheck
     tags:
       - { name: access_check }
+  access_check.entity:
+    class: Drupal\Core\Entity\EntityAccessCheck
+    tags:
+      - { name: access_check }
   maintenance_mode_subscriber:
     class: Drupal\Core\EventSubscriber\MaintenanceModeSubscriber
     tags:
diff --git a/core/lib/Drupal/Core/Entity/EntityAccessCheck.php b/core/lib/Drupal/Core/Entity/EntityAccessCheck.php
new file mode 100644
index 0000000..391db5b
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/EntityAccessCheck.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\EntityAccessCheck.
+ */
+
+namespace Drupal\Core\Entity;
+
+use Drupal\Core\Entity\EntityInterface;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\HttpFoundation\Request;
+use Drupal\Core\Access\AccessCheckInterface;
+
+/**
+ * Provides a generic access checker for entities.
+ */
+class EntityAccessCheck implements AccessCheckInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function applies(Route $route) {
+    return array_key_exists('_entity_access', $route->getRequirements());
+  }
+
+  /**
+   * Implements \Drupal\Core\Access\AccessCheckInterface::access().
+   *
+   * The value of the '_entity_access' key must be in the pattern
+   * 'slug.operation.' The slug corresponds to the named param {slug}.
+   * This will check a node for 'update' access:
+   * @code
+   * pattern: '/foo/{node}/bar'
+   * requirements:
+   *   _entity_access: 'node.update'
+   * @endcode
+   */
+  public function access(Route $route, Request $request) {
+    // Split the slug and the operation.
+    $requirement = $route->getRequirement('_entity_access');
+    list($slug, $operation) = explode('.', $requirement);
+    // If this slug is in the request, and it is an entity, check its access.
+    if ($request->attributes->has($slug)) {
+      $entity = $request->attributes->get($slug);
+      if ($entity instanceof EntityInterface) {
+        return $entity->access($operation);
+      }
+    }
+    // No opinion, so other access checks should decide if access should be
+    // allowed or not.
+    return NULL;
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityAccessCheckTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityAccessCheckTest.php
new file mode 100644
index 0000000..895a198
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Entity/EntityAccessCheckTest.php
@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Entity\EntityAccessCheckTest.
+ */
+
+namespace Drupal\Tests\Core\Entity;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
+use Drupal\Core\Entity\EntityAccessCheck;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Tests the entity access controller.
+ *
+ * @group Entity
+ */
+class EntityAccessCheckTest extends UnitTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Entity access check test',
+      'description' => 'Unit test of entity access checking system.',
+      'group' => 'Entity'
+    );
+  }
+
+  /**
+   * Tests the method for checking if the access check applies to a route.
+   */
+  public function testApplies() {
+    $applies_check = new EntityAccessCheck();
+
+    $route = $this->getMockBuilder('Symfony\Component\Routing\Route')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $route->expects($this->any())
+      ->method('getRequirements')
+      ->will($this->returnValue(array('_entity_access' => '')));
+    $res = $applies_check->applies($route);
+    $this->assertEquals(TRUE, $res);
+
+    $route = $this->getMockBuilder('Symfony\Component\Routing\Route')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $route->expects($this->any())
+      ->method('getRequirements')
+      ->will($this->returnValue(array()));
+    $res = $applies_check->applies($route);
+    $this->assertEquals(FALSE, $res);
+  }
+
+  /**
+   * Tests the method for checking access to routes.
+   */
+  public function testAccess() {
+    $route = new Route('/foo', array(), array('_entity_access' => 'node.update'));
+    $request = new Request();
+    $node = $this->getMockBuilder('Drupal\node\Plugin\Core\Entity\Node')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $node->expects($this->any())
+      ->method('access')
+      ->will($this->returnValue(TRUE));
+    $access_check = new EntityAccessCheck();
+    $request->attributes->set('node', $node);
+    $access = $access_check->access($route, $request);
+    $this->assertEquals(TRUE, $access);
+  }
+
+}
