diff --git a/config/schema/entity.schema.yml b/config/schema/entity.schema.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a70ef2a1fb704a377884034785bf44140b9a44d2
--- /dev/null
+++ b/config/schema/entity.schema.yml
@@ -0,0 +1,7 @@
+views.field.rendered_entity:
+  type: views_field
+  label: 'Rendered entity'
+  mapping:
+    view_mode:
+      type: string
+      label: 'View mode'
diff --git a/entity.views.inc b/entity.views.inc
new file mode 100644
index 0000000000000000000000000000000000000000..f4d5db32f420c3b15c2110513d022792377c958d
--- /dev/null
+++ b/entity.views.inc
@@ -0,0 +1,32 @@
+<?php
+
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+
+/**
+ * Implements hook_views_data().
+ */
+function entity_views_data() {
+  $entity_types = \Drupal::entityTypeManager()->getDefinitions();
+  $entity_types = array_filter($entity_types, function (EntityTypeInterface $entity_type) {
+    return $entity_type->isSubclassOf(ContentEntityInterface::class);
+  });
+
+  $data = [];
+  foreach ($entity_types as $entity_type) {
+    /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
+    $base_table = $entity_type->getBaseTable() ?: $entity_type->id();
+
+    if ($entity_type->hasViewBuilderClass()) {
+      $data[$base_table]['rendered_entity'] = [
+        'field' => [
+          'title' => t('Rendered entity'),
+          'help' => t('Renders an entity in a view mode.'),
+          'id' => 'rendered_entity',
+        ],
+      ];
+    }
+  }
+
+  return $data;
+}
diff --git a/src/Plugin/views/field/RenderedEntity.php b/src/Plugin/views/field/RenderedEntity.php
new file mode 100644
index 0000000000000000000000000000000000000000..27f99462a8b5075b2fdf0775cfb3b5563af0d75a
--- /dev/null
+++ b/src/Plugin/views/field/RenderedEntity.php
@@ -0,0 +1,207 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity\Plugin\views\field\RenderedEntity.
+ */
+
+namespace Drupal\entity\Plugin\views\field;
+
+use Drupal\Core\Cache\CacheableDependencyInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Language\LanguageManagerInterface;
+use Drupal\views\Entity\Render\EntityTranslationRenderTrait;
+use Drupal\views\ResultRow;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a field handler which renders an entity in a certain view mode.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @ViewsField("rendered_entity")
+ */
+class RenderedEntity extends FieldPluginBase implements CacheableDependencyInterface {
+
+  use EntityTranslationRenderTrait;
+
+  /**
+   * The entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $entityManager;
+
+  /**
+   * The language manager.
+   *
+   * @var \Drupal\Core\Language\LanguageManagerInterface
+   */
+  protected $languageManager;
+
+  /**
+   * Constructs a new RenderedEntity object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param array $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *    The entity manager.
+   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
+   *   The language manager.
+   */
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->entityManager = $entity_manager;
+    $this->languageManager = $language_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'),
+      $container->get('language_manager')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function usesGroupBy() {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defineOptions() {
+    $options = parent::defineOptions();
+    $options['view_mode'] = ['default' => 'default'];
+
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
+    parent::buildOptionsForm($form, $form_state);
+
+    $form['view_mode'] = [
+      '#type' => 'select',
+      '#options' => $this->entityManager->getViewModeOptions($this->getEntityTypeId()),
+      '#title' => $this->t('View mode'),
+      '#default_value' => $this->options['view_mode'],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function render(ResultRow $values) {
+    $entity = $this->getEntityTranslation($this->getEntity($values), $values);
+    if (isset($entity) && $entity->access('view')) {
+      $view_builder = $this->entityManager->getViewBuilder($this->getEntityTypeId());
+      return $view_builder->view($entity, $this->options['view_mode']);
+    }
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheContexts() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheTags() {
+    $view_display_storage = $this->entityManager->getStorage('entity_view_display');
+    $view_displays = $view_display_storage->loadMultiple($view_display_storage
+      ->getQuery()
+      ->condition('targetEntityType', $this->getEntityTypeId())
+      ->execute());
+
+    $tags = [];
+    foreach ($view_displays as $view_display) {
+      $tags = array_merge($tags, $view_display->getCacheTags());
+    }
+    return $tags;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheMaxAge() {
+    return 0;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    // We purposefully do not call parent::query() because we do not want the
+    // default query behavior for Views fields. Instead, let the entity
+    // translation renderer provide the correct query behavior.
+    if ($this->languageManager->isMultilingual()) {
+      $this->getEntityTranslationRenderer()->query($this->query, $this->relationship);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getEntityTypeId() {
+    return $this->getEntityType();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEntityManager() {
+    return $this->entityManager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getLanguageManager() {
+    return $this->languageManager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getView() {
+    return $this->view;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function calculateDependencies() {
+    $dependencies = parent::calculateDependencies();
+
+    $view_mode = $this->entityManager
+      ->getStorage('entity_view_mode')
+      ->load($this->entityTypeId . '.' . $this->options['view_mode']);
+    if ($view_mode) {
+      $dependencies[$view_mode->getConfigDependencyKey()][] = $view_mode->getConfigDependencyName();
+    }
+
+    return $dependencies;
+  }
+
+}
diff --git a/src/Tests/Plugin/views/field/RenderedEntityTest.php b/src/Tests/Plugin/views/field/RenderedEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d50a37f92ac70022d6a879ad2414ec8e550f378c
--- /dev/null
+++ b/src/Tests/Plugin/views/field/RenderedEntityTest.php
@@ -0,0 +1,164 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity\Tests\Plugin\views\field\RenderedEntityTest.
+ */
+
+namespace Drupal\entity\Tests\Plugin\views\field;
+
+use Drupal\Core\Entity\Entity\EntityViewDisplay;
+use Drupal\entity_test\Entity\EntityTest;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\user\Entity\Role;
+use Drupal\user\Entity\User;
+use Drupal\views\Tests\ViewKernelTestBase;
+use Drupal\views\Tests\ViewTestData;
+use Drupal\views\Views;
+use Drupal\Core\Entity\Entity\EntityViewMode;
+
+/**
+ * Tests the Drupal\entity\Plugin\views\field\RenderedEntity handler.
+ *
+ * @group entity
+ */
+class RenderedEntityTest extends ViewKernelTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['entity_test', 'entity_module_test', 'field'];
+
+  /**
+   * Views used by this test.
+   *
+   * @var array
+   */
+  public static $testViews = ['test_entity_rendered'];
+
+  /**
+   * The logged in user.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $user;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    if ($import_test_views) {
+      ViewTestData::createTestViews(get_class($this), ['entity_module_test']);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUpFixtures() {
+    $this->installEntitySchema('user');
+    $this->installEntitySchema('entity_test');
+    $this->installConfig(['entity_test']);
+
+    EntityViewMode::create([
+      'id' => 'entity_test.foobar',
+      'targetEntityType' => 'entity_test',
+      'status' => TRUE,
+      'enabled' => TRUE,
+      'label' => 'My view mode',
+    ])->save();
+
+    $display = EntityViewDisplay::create([
+      'targetEntityType' => 'entity_test',
+      'bundle' => 'entity_test',
+      'mode' => 'foobar',
+      'label' => 'My view mode',
+      'status' => TRUE,
+    ]);
+    $display->save();
+
+    $field_storage = FieldStorageConfig::create([
+      'field_name' => 'test_field',
+      'entity_type' => 'entity_test',
+      'type' => 'string',
+    ]);
+    $field_storage->save();
+
+    $field_config = FieldConfig::create([
+      'field_name' => 'test_field',
+      'entity_type' => 'entity_test',
+      'bundle' => 'entity_test',
+    ]);
+    $field_config->save();
+
+    // Create some test entities.
+    for ($i = 1; $i <= 3; $i++) {
+      EntityTest::create([
+        'name' => "Article title $i",
+        'test_field' => "Test $i",
+      ])->save();
+    }
+
+    $role = Role::create([
+      'id' => 'test_role',
+    ]);
+    $role->grantPermission('bypass node access');
+    $role->save();
+    $this->user = User::create([
+      'name' => 'test user',
+    ]);
+    $this->user->addRole($role->id());
+    $this->user->save();
+
+    parent::setUpFixtures();
+  }
+
+  /**
+   * Tests the default rendered entity output.
+   */
+  public function testRenderedEntityWithoutField() {
+    \Drupal::currentUser()->setAccount($this->user);
+
+    EntityViewDisplay::load('entity_test.entity_test.foobar')
+      ->removeComponent('test_field')
+      ->save();
+
+    // The view should not display the body field.
+    $view = Views::getView('test_field_entity_test_rendered');
+    $build = $view->preview();
+    $renderer = \Drupal::service('renderer');
+    $renderer->renderPlain($build);
+    for ($i = 1; $i <= 3; $i++) {
+      $view_field = $view->style_plugin->getField($i - 1, 'rendered_entity');
+      $search_result = strpos($view_field, "Test $i") !== FALSE;
+      $this->assertFalse($search_result, "The text 'Test $i' not found in the view.");
+    }
+  }
+
+  /**
+   * Tests the rendered entity output with the body field configured to show.
+   */
+  public function testRenderedEntityWithField() {
+    \Drupal::currentUser()->setAccount($this->user);
+
+    // Show the body on the node.x.foobar view mode.
+    EntityViewDisplay::load('entity_test.entity_test.foobar')->setComponent('test_field', ['type' => 'string', 'label' => 'above'])->save();
+
+    // The view should display the body field.
+    $view = Views::getView('test_field_entity_test_rendered');
+    $build = $view->preview();
+    $renderer = \Drupal::service('renderer');
+    $renderer->renderPlain($build);
+    for ($i = 1; $i <= 3; $i++) {
+      $view_field = $view->style_plugin->getField($i - 1, 'rendered_entity');
+      $search_result = strpos($view_field, "Test $i") !== FALSE;
+      $this->assertTrue($search_result, "The text 'Test $i' found in the view.");
+    }
+  }
+
+}
diff --git a/tests/modules/entity_module_test/test_views/views.view.test_field_entity_test_rendered.yml b/tests/modules/entity_module_test/test_views/views.view.test_field_entity_test_rendered.yml
new file mode 100644
index 0000000000000000000000000000000000000000..541ee969306fd6c9efc62c1057f8988eac093ede
--- /dev/null
+++ b/tests/modules/entity_module_test/test_views/views.view.test_field_entity_test_rendered.yml
@@ -0,0 +1,161 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - entity_test
+    - user
+id: test_field_entity_test_rendered
+label: 'Test Rendered entity test'
+module: views
+description: ''
+tag: ''
+base_table: entity_test
+base_field: id
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: none
+        options: {  }
+      cache:
+        type: none
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: full
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: '‹ Previous'
+            next: 'Next ›'
+            first: '« First'
+            last: 'Last »'
+          quantity: 9
+      style:
+        type: default
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          uses_fields: false
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        rendered_entity:
+          id: rendered_entity
+          table: entity_test
+          field: rendered_entity
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          view_mode: foobar
+          entity_type: entity_test
+          plugin_id: rendered_entity
+      filters: {  }
+      sorts:
+        id:
+          id: id
+          table: entity_test
+          field: id
+          relationship: none
+          group_type: group
+          admin_label: ''
+          order: ASC
+          exposed: false
+          expose:
+            label: ''
+          entity_type: entity_test
+          entity_field: nid
+          plugin_id: standard
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+    cache_metadata:
+      max-age: 0
+      contexts:
+        - 'languages:language_interface'
+        - url.query_args
+        - user.permissions
+      tags: { }