diff --git a/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php b/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php
new file mode 100644
index 0000000..850d04b
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\Controller\EntityViewController.
+ */
+
+namespace Drupal\Core\Entity\Controller;
+
+use Drupal\Core\Controller\ControllerInterface;
+use Drupal\Core\Entity\EntityManager;
+use Drupal\Core\Entity\EntityInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Defines a generic controller to render a single entity.
+ */
+class EntityViewController implements ControllerInterface {
+
+  /**
+   * The entity manager
+   *
+   * @var \Drupal\Core\Entity\EntityManager
+   */
+  protected $entityManager;
+
+  /**
+   * Creates an EntityListController object.
+   *
+   * @param \Drupal\Core\Entity\EntityManager $entity_manager
+   *   The entity manager.
+   */
+  public function __construct(EntityManager $entity_manager) {
+    $this->entityManager = $entity_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('plugin.manager.entity')
+    );
+  }
+
+  /**
+   * Provides a page to render a single entity.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The Entity to be rendered.
+   * @param string $view_mode
+   *   The view mode that should be used to display the entity.
+   * @param string $langcode
+   *   (optional) For which language the entity should be rendered, defaults to
+   *   the current content language.
+   *
+   * @return array
+   *   A render array as expected by drupal_render().
+   */
+  public function view(EntityInterface $entity, $view_mode, $langcode = NULL) {
+    return $this->entityManager
+      ->getRenderController($entity->entityType())
+      ->view($entity, $view_mode, $langcode);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Entity/Enhancer/EntityRouteEnhancer.php b/core/lib/Drupal/Core/Entity/Enhancer/EntityRouteEnhancer.php
index f2f6648..d8e5cd5 100644
--- a/core/lib/Drupal/Core/Entity/Enhancer/EntityRouteEnhancer.php
+++ b/core/lib/Drupal/Core/Entity/Enhancer/EntityRouteEnhancer.php
@@ -9,6 +9,7 @@
 
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface;
+use Symfony\Cmf\Component\Routing\RouteObjectInterface;
 use Drupal\Core\ContentNegotiation;
 
 /**
@@ -47,6 +48,29 @@ public function enhance(array $defaults, Request $request) {
         $defaults['entity_type'] = $defaults['_entity_list'];
         unset($defaults['_entity_list']);
       }
+      elseif (!empty($defaults['_entity_view'])) {
+        $defaults['_controller'] = 'controller.page:content';
+        $defaults['_content'] = '\Drupal\Core\Entity\Controller\EntityViewController::view';
+        list($entity_type, $view_mode) = explode('.', $defaults['_entity_view']);
+        // Set by reference so that we get the upcast value.
+        if (!empty($defaults[$entity_type])) {
+          $defaults['entity'] = &$defaults[$entity_type];
+        }
+        else {
+          // The entity is not keyed by its entity_type. Attempt to find it
+          // using a converter.
+          $route = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT);
+          $options = $route->getOptions();
+          if (isset($options['converters'])) {
+            $flipped = array_flip($options['converters']);
+            if (isset($flipped[$entity_type]) && !empty($defaults[$flipped[$entity_type]])) {
+              $defaults['entity'] = $defaults[$flipped[$entity_type]];
+            }
+          }
+        }
+        $defaults['view_mode'] = $view_mode;
+        unset($defaults['_entity_view']);
+      }
     }
     return $defaults;
   }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityViewControllerTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityViewControllerTest.php
new file mode 100644
index 0000000..8c885ac
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityViewControllerTest.php
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\Entity\EntityViewControllerTest.
+ */
+
+namespace Drupal\system\Tests\Entity;
+
+use Drupal\simpletest\WebTestBase;
+use Drupal\Core\Language\Language;
+
+/**
+ * Tests \Drupal\Core\Entity\Controller\EntityViewController.
+ */
+class EntityViewControllerTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('entity_test');
+
+  /**
+   * Array of test entities.
+   *
+   * @var array
+   */
+  protected $entities = array();
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Entity View Controller',
+      'description' => 'Tests EntityViewController functionality.',
+      'group' => 'Entity API',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    // Create some dummy entity_test_render entities.
+    for ($i = 0; $i < 2; $i++) {
+      $random_label = $this->randomName();
+      $data = array('bundle' => 'entity_test_render', 'name' => $random_label);
+      $entity_test = $this->container->get('plugin.manager.entity')->getStorageController('entity_test_render')->create($data);
+      $entity_test->save();
+      $this->entities[] = $entity_test;
+    }
+
+  }
+
+  /**
+   * Tests EntityViewController.
+   */
+  function testEntityViewController() {
+    foreach ($this->entities as $entity) {
+      $this->drupalGet('entity-test-render/' . $entity->id());
+      $this->assertRaw($entity->label());
+      $this->assertRaw('full');
+
+      $this->drupalGet('entity-test-render-converter/' . $entity->id());
+      $this->assertRaw($entity->label());
+      $this->assertRaw('full');
+    }
+  }
+}
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.routing.yml b/core/modules/system/tests/modules/entity_test/entity_test.routing.yml
new file mode 100644
index 0000000..6cf2319
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test/entity_test.routing.yml
@@ -0,0 +1,16 @@
+entity_test_render:
+  pattern: '/entity-test-render/{entity_test_render}'
+  defaults:
+    _entity_view: 'entity_test_render.full'
+  requirements:
+    _access: 'TRUE'
+
+entity_test_render_options:
+  pattern: '/entity-test-render-converter/{foo}'
+  options:
+    converters:
+      foo: 'entity_test_render'
+  defaults:
+    _entity_view: 'entity_test_render.full'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/tests/Drupal/Tests/Core/Entity/Controller/EntityViewControllerTest.php b/core/tests/Drupal/Tests/Core/Entity/Controller/EntityViewControllerTest.php
new file mode 100644
index 0000000..cfa1e29
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Entity/Controller/EntityViewControllerTest.php
@@ -0,0 +1,62 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Entity\Controller\EntityViewControllerTest.
+ */
+
+namespace Drupal\Core\Tests\Entity\Controller;
+
+use Drupal\Core\Entity\Controller\EntityViewController;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Tests the entity view controller.
+ *
+ * @see \Drupal\Core\Entity\Controller\EntityViewController
+ */
+class EntityViewControllerTest extends UnitTestCase{
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Entity route enhancer test',
+      'description' => 'Tests the entity route enhancer.',
+      'group' => 'Entity'
+    );
+  }
+
+  /**
+   * Tests the enhancer method.
+   *
+   * @see \Drupal\Core\Entity\Controller\EntityViewController::view()
+   */
+  public function testView() {
+
+    // Mock a render controller.
+    $render_controller = $this->getMockBuilder('Drupal\entity_test\EntityTestRenderController')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $render_controller->expects($this->any())
+      ->method('view')
+      ->will($this->returnValue('Output from rendering the entity'));
+
+    // Mock an entity manager.
+    $entity_manager = $this->getMockBuilder('Drupal\Core\Entity\EntityManager')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $entity_manager->expects($this->any())
+      ->method('getRenderController')
+      ->will($this->returnValue($render_controller));
+
+    // Mock an 'entity_test_render' entity.
+    $entity = $this->getMockBuilder('Drupal\entity_test\Plugin\Core\Entity\EntityTestRender')
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    // Initialize the controller to test.
+    $controller = new EntityViewController($entity_manager);
+
+    // Test the view method.
+    $this->assertEquals($controller->view($entity, 'full'), 'Output from rendering the entity');
+  }
+}
diff --git a/core/tests/Drupal/Tests/Core/Entity/Enhancer/EntityRouteEnhancerTest.php b/core/tests/Drupal/Tests/Core/Entity/Enhancer/EntityRouteEnhancerTest.php
index ffd60a1..00bae1c 100644
--- a/core/tests/Drupal/Tests/Core/Entity/Enhancer/EntityRouteEnhancerTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/Enhancer/EntityRouteEnhancerTest.php
@@ -10,6 +10,7 @@
 use Drupal\Core\ContentNegotiation;
 use Drupal\Core\Entity\Enhancer\EntityRouteEnhancer;
 use Drupal\Tests\UnitTestCase;
+use Symfony\Cmf\Component\Routing\RouteObjectInterface;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
@@ -62,6 +63,41 @@ public function testEnhancer() {
     $this->assertEquals('\Drupal\Core\Entity\Controller\EntityListController::listing', $defaults['_content'], 'The entity list controller was not set.');
     $this->assertEquals('entity_test.default', $defaults['entity_type']);
     $this->assertFalse(isset($defaults['_entity_list']));
+
+    // Set _entity_view and ensure that the entity view controller is set.
+    $defaults = array();
+    $defaults['_entity_view'] = 'entity_test.default';
+    $defaults['entity_test'] = 'Mock entity';
+    $defaults = $route_enhancer->enhance($defaults, $request);
+    $this->assertEquals('controller.page:content', $defaults['_controller']);
+    $this->assertEquals('\Drupal\Core\Entity\Controller\EntityViewController::view', $defaults['_content'], 'The entity view controller was not set.');
+    $this->assertEquals($defaults['entity'], 'Mock entity');
+    $this->assertEquals($defaults['view_mode'], 'default');
+    $this->assertFalse(isset($defaults['_entity_view']));
+
+    // Set _entity_view and ensure that the entity view controller is set using
+    // a converter.
+    $defaults = array();
+    $defaults['_entity_view'] = 'entity_test.default';
+    $defaults['foo'] = 'Mock entity';
+    // Add a converter.
+    $options['converters']['foo'] = 'entity_test';
+    // Set the route.
+    $route = $this->getMockBuilder('Symfony\Component\Routing\Route')
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    $route->expects($this->any())
+      ->method('getOptions')
+      ->will($this->returnValue($options));
+
+    $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, $route);
+    $defaults = $route_enhancer->enhance($defaults, $request);
+    $this->assertEquals('controller.page:content', $defaults['_controller']);
+    $this->assertEquals('\Drupal\Core\Entity\Controller\EntityViewController::view', $defaults['_content'], 'The entity view controller was not set.');
+    $this->assertEquals($defaults['entity'], 'Mock entity');
+    $this->assertEquals($defaults['view_mode'], 'default');
+    $this->assertFalse(isset($defaults['_entity_view']));
   }
 
 }
