diff --git a/core/modules/node/src/NodeViewsData.php b/core/modules/node/src/NodeViewsData.php
index a71f834..e8a0219 100644
--- a/core/modules/node/src/NodeViewsData.php
+++ b/core/modules/node/src/NodeViewsData.php
@@ -36,7 +36,6 @@ public function getViewsData() {
     $data['node_field_data']['title']['field']['id'] = 'node';
     $data['node_field_data']['title']['field']['link_to_node default'] = TRUE;
 
-    $data['node_field_data']['type']['field']['id'] = 'node_type';
     $data['node_field_data']['type']['argument']['id'] = 'node_type';
 
     $data['node_field_data']['langcode']['help'] = t('The language of the content or translation.');
diff --git a/core/modules/views/src/EntityViewsData.php b/core/modules/views/src/EntityViewsData.php
index b2859d0..c6e0ff4 100644
--- a/core/modules/views/src/EntityViewsData.php
+++ b/core/modules/views/src/EntityViewsData.php
@@ -419,9 +419,8 @@ protected function processViewsDataForEntityReference($table, FieldDefinitionInt
     }
 
     if ($field_definition->getName() == $this->entityType->getKey('bundle')) {
-      // @todo Use the other bundle handlers, once
-      //   https://www.drupal.org/node/2322949 is in.
       $views_field['filter']['id'] = 'bundle';
+      $views_field['field']['id'] = 'bundle';
     }
   }
 
diff --git a/core/modules/views/src/Plugin/views/field/Bundle.php b/core/modules/views/src/Plugin/views/field/Bundle.php
new file mode 100644
index 0000000..b6f6f1c
--- /dev/null
+++ b/core/modules/views/src/Plugin/views/field/Bundle.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Plugin\views\field\Bundle.
+ */
+
+namespace Drupal\views\Plugin\views\field;
+
+use Drupal\Core\Entity\EntityManagerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Field handler to present a bundle to the entity_bundle.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @ViewsField("bundle")
+ */
+class Bundle extends MachineName {
+
+  /**
+   * The entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $entityManager;
+
+  /**
+   * Constructs a Bundle instance.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->entityManager = $entity_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity.manager')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getValueOptions() {
+    if (isset($this->valueOptions)) {
+      return;
+    }
+
+    $bundles = $this->entityManager->getBundleInfo($this->configuration['entity type']);
+    $this->valueOptions = [];
+    foreach ($bundles as $name => $info) {
+      $this->valueOptions[$name] = $info['label'];
+    }
+  }
+
+}
diff --git a/core/modules/views/src/Plugin/views/field/Entity.php b/core/modules/views/src/Plugin/views/field/Entity.php
new file mode 100644
index 0000000..b1f1af0
--- /dev/null
+++ b/core/modules/views/src/Plugin/views/field/Entity.php
@@ -0,0 +1,149 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Plugin\views\field\Entity.
+ */
+
+namespace Drupal\views\Plugin\views\field;
+
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\views\ResultRow;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Field handler to present a bundle to the entity_bundle.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @ViewsField("entity_view")
+ */
+class Entity extends FieldPluginBase {
+
+  /**
+   * The entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $entityManager;
+
+  /**
+   * Constructs a Entity instance.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->entityManager = $entity_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity.manager')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineOptions() {
+    $options = parent::defineOptions();
+
+    $options['display'] = ['default' => 'label'];
+    $options['link_to_entity']['default'] = TRUE;
+    $options['view_mode'] = ['default' => 'default'];
+    $options['bypass_access'] = ['default' => FALSE];
+
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
+    $options = [
+      'label' => $this->t('Show entity label'),
+      'id' => $this->t('Show entity ID'),
+      'view' => $this->t('Show complete entity'),
+    ];
+
+    $form['display'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Display'),
+      '#description' => $this->t('Decide how this field will be displayed.'),
+      '#options' => $options,
+      '#default_value' => $this->options['display'],
+    ];
+
+    $form['link_to_entity'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Link to entity'),
+      '#description' => $this->t('Link this field to the entity.'),
+      '#default_value' => $this->options['link_to_entity'],
+      '#states' => [
+        'invisible' => [
+          ':input[name="options[display]"]' => ['value' => 'view'],
+        ],
+      ],
+    ];
+
+    // Stolen from entity_views_plugin_row_entity_view.
+    $view_modes = [];
+    foreach ($this->entityManager->getViewModes($this->getEntityType()) as $mode => $settings) {
+      $view_modes[$mode] = $settings['label'];
+    }
+
+    if (count($view_modes) > 1) {
+      $form['view_mode'] = [
+        '#type' => 'select',
+        '#options' => $view_modes,
+        '#title' => $this->t('View mode'),
+        '#default_value' => $this->options['view_mode'],
+        '#states' => [
+          'visible' => [
+            ':input[name="options[display]"]' => ['value' => 'view'],
+          ],
+        ],
+      ];
+    }
+    else {
+      $form['view_mode'] = [
+        '#type' => 'value',
+        '#value' => 'default',
+      ];
+    }
+
+    $form['bypass_access'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Bypass access checks'),
+      '#description' => $this->t('If enabled, access permissions for rendering the entity are not checked.'),
+      '#default_value' => !empty($this->options['bypass_access']),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function render(ResultRow $values) {
+    $entity = $this->getEntity($values);
+
+    $render_controller = $this->entityManager->getViewBuilder($entity->getEntityTypeId());
+    return $render_controller->view($entity, $this->options['view_mode']);
+  }
+
+}
diff --git a/core/modules/views/src/Plugin/views/field/EntityLink.php b/core/modules/views/src/Plugin/views/field/EntityLink.php
new file mode 100644
index 0000000..d3ed3c6
--- /dev/null
+++ b/core/modules/views/src/Plugin/views/field/EntityLink.php
@@ -0,0 +1,92 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Plugin\views\field\EntityLink.
+ */
+
+namespace Drupal\views\Plugin\views\field;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\views\Plugin\views\field\FieldPluginBase;
+use Drupal\views\ResultRow;
+
+/**
+ * Field handler to present a link to the entity_link.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @ViewsField("entity_link")
+ */
+class EntityLink extends FieldPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function usesGroupBy() {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineOptions() {
+    $options = parent::defineOptions();
+    $options['text'] = ['default' => '', 'translatable' => TRUE];
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
+    $form['text'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Text to display'),
+      '#default_value' => $this->options['text'],
+    ];
+    parent::buildOptionsForm($form, $form_state);
+
+    // The path is set by renderLink function so don't allow to set it.
+    $form['alter']['path'] = ['#access' => FALSE];
+    $form['alter']['external'] = ['#access' => FALSE];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    $this->addAdditionalFields();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function render(ResultRow $values) {
+    if ($entity = $this->getEntity($values)) {
+      return $this->renderLink($entity, $values);
+    }
+  }
+
+  /**
+   * Prepares the link to view a entity.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The node entity this field belongs to.
+   * @param \Drupal\views\ResultRow $values
+   *   The values retrieved from the view's result set.
+   *
+   * @return string
+   *   Returns a string for the link text.
+   */
+  protected function renderLink($entity, ResultRow $values) {
+    if ($entity->access('view')) {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = $entity->getSystemPath();
+
+      $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('view');
+      return $text;
+    }
+  }
+
+}
diff --git a/core/modules/views/src/Plugin/views/field/EntityLinkDelete.php b/core/modules/views/src/Plugin/views/field/EntityLinkDelete.php
new file mode 100644
index 0000000..9f2d7b0
--- /dev/null
+++ b/core/modules/views/src/Plugin/views/field/EntityLinkDelete.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Plugin\views\field\EntityLinkDelete.
+ */
+
+namespace Drupal\views\Plugin\views\field;
+
+use Drupal\views\ResultRow;
+
+/**
+ * Field handler to present a link to delete an entity.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @ViewsField("entity_link_delete")
+ */
+class EntityLinkDelete extends EntityLink {
+
+  /**
+   * Prepares the link to delete an entity.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The node entity this field belongs to.
+   * @param \Drupal\views\ResultRow $values
+   *   The values retrieved from the view's result set.
+   *
+   * @return string
+   *   Returns a string for the link text.
+   */
+  protected function renderLink($entity, ResultRow $values) {
+    // Ensure user has access to delete this node.
+    if ($entity && $entity->access('delete')) {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = $entity->getSystemPath('delete-form');
+      $this->options['alter']['query'] = drupal_get_destination();
+
+      $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('delete');
+      return $text;
+    }
+  }
+
+}
diff --git a/core/modules/views/src/Plugin/views/field/EntityLinkEdit.php b/core/modules/views/src/Plugin/views/field/EntityLinkEdit.php
new file mode 100644
index 0000000..bca8dea
--- /dev/null
+++ b/core/modules/views/src/Plugin/views/field/EntityLinkEdit.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Plugin\views\field\EntityLinkEdit.
+ */
+
+namespace Drupal\views\Plugin\views\field;
+
+use Drupal\views\ResultRow;
+
+/**
+ * Field handler to present a link to edit an entity.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @ViewsField("entity_link_edit")
+ */
+class EntityLinkEdit extends EntityLink {
+
+  /**
+   * Prepares the link to edit an entity.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The node entity this field belongs to.
+   * @param \Drupal\views\ResultRow $values
+   *   The values retrieved from the view's result set.
+   *
+   * @return string
+   *   Returns a string for the link text.
+   */
+  protected function renderLink($entity, ResultRow $values) {
+    // Ensure user has access to delete this node.
+    if ($entity && $entity->access('delete')) {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = $entity->getSystemPath('delete-form');
+      $this->options['alter']['query'] = drupal_get_destination();
+
+      $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('delete');
+      return $text;
+    }
+  }
+
+}
diff --git a/core/modules/views/src/Tests/Handler/FieldBundleTest.php b/core/modules/views/src/Tests/Handler/FieldBundleTest.php
new file mode 100644
index 0000000..4f9fb83
--- /dev/null
+++ b/core/modules/views/src/Tests/Handler/FieldBundleTest.php
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Tests\Handler\FieldBundleTest.
+ */
+
+namespace Drupal\views\Tests\Handler;
+
+use Drupal\views\Tests\ViewUnitTestBase;
+
+class FieldBundleTest extends ViewUnitTestBase {
+
+}
+
diff --git a/core/modules/views/src/Tests/Handler/FieldEntityLinkTest.php b/core/modules/views/src/Tests/Handler/FieldEntityLinkTest.php
new file mode 100644
index 0000000..df8120b
--- /dev/null
+++ b/core/modules/views/src/Tests/Handler/FieldEntityLinkTest.php
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Tests\Handler\FieldEntityLinkTest.
+ */
+
+namespace Drupal\views\Tests\Handler;
+
+use Drupal\views\Tests\ViewUnitTestBase;
+
+class FieldEntityLinkTest extends ViewUnitTestBase {
+
+}
+
diff --git a/core/modules/views/src/Tests/Handler/FieldEntityTest.php b/core/modules/views/src/Tests/Handler/FieldEntityTest.php
new file mode 100644
index 0000000..62908ee
--- /dev/null
+++ b/core/modules/views/src/Tests/Handler/FieldEntityTest.php
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Tests\Handler\FieldEntityTest.
+ */
+
+namespace Drupal\views\Tests\Handler;
+
+use Drupal\views\Tests\ViewUnitTestBase;
+
+class FieldEntityTest extends ViewUnitTestBase {
+
+}
+
diff --git a/core/modules/views/tests/Drupal/views/Tests/EntityViewsDataTest.php b/core/modules/views/tests/Drupal/views/Tests/EntityViewsDataTest.php
index 4618309..6ab959e 100644
--- a/core/modules/views/tests/Drupal/views/Tests/EntityViewsDataTest.php
+++ b/core/modules/views/tests/Drupal/views/Tests/EntityViewsDataTest.php
@@ -580,7 +580,7 @@ protected function assertEntityReferenceField($data) {
    * Tests views data for a bundle field.
    */
   protected function assertBundleField($data) {
-    $this->assertEquals('standard', $data['field']['id']);
+    $this->assertEquals('bundle', $data['field']['id']);
     $this->assertEquals('bundle', $data['filter']['id']);
     $this->assertEquals('string', $data['argument']['id']);
     $this->assertEquals('standard', $data['sort']['id']);
