diff --git a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
index 9d6b8d64f5..f6e8155380 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -35,6 +36,13 @@
   protected $cacheBackend;
 
   /**
+   * The entity type bundle information object.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
+   */
+  protected $entityTypeBundleInfo;
+
+  /**
    * Constructs a ContentEntityStorageBase object.
    *
    * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
@@ -43,12 +51,15 @@
    *   The entity manager.
    * @param \Drupal\Core\Cache\CacheBackendInterface $cache
    *   The cache backend to be used.
+   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
+   *   The entity type bundle information object.
    */
-  public function __construct(EntityTypeInterface $entity_type, EntityManagerInterface $entity_manager, CacheBackendInterface $cache) {
+  public function __construct(EntityTypeInterface $entity_type, EntityManagerInterface $entity_manager, CacheBackendInterface $cache, EntityTypeBundleInfoInterface $entity_type_bundle_info) {
     parent::__construct($entity_type);
     $this->bundleKey = $this->entityType->getKey('bundle');
     $this->entityManager = $entity_manager;
     $this->cacheBackend = $cache;
+    $this->entityTypeBundleInfo = $entity_type_bundle_info;
   }
 
   /**
@@ -58,7 +69,8 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
     return new static(
       $entity_type,
       $container->get('entity.manager'),
-      $container->get('cache.entity')
+      $container->get('cache.entity'),
+      $container->get('entity_type.bundle.info')
     );
   }
 
@@ -90,6 +102,40 @@ protected function doCreate(array $values) {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function createWithSampleValues($bundle = FALSE, array $values = []) {
+    // ID and revision should never have sample values generated for them.
+    $forbidden_keys = [
+      $this->entityType->getKey('id'),
+    ];
+    if ($revision_key = $this->entityType->getKey('revision')) {
+      $forbidden_keys[] = $revision_key;
+    }
+    if ($bundle_key = $this->entityType->getKey('bundle')) {
+      if (!$bundle) {
+        throw new EntityStorageException("No entity bundle was specified");
+      }
+      if (!array_key_exists($bundle, $this->entityTypeBundleInfo->getBundleInfo($this->entityTypeId))) {
+        throw new EntityStorageException(sprintf("Missing entity bundle. The \"%s\" bundle does not exist", $bundle));
+      }
+      $values[$bundle_key] = $bundle;
+      // Bundle is already set
+      $forbidden_keys[] = $bundle_key;
+    }
+    // Forbid sample generation on any keys whose values were submitted.
+    $forbidden_keys = array_merge($forbidden_keys, array_keys($values));
+    /** @var \Drupal\Core\Entity\FieldableEntityInterface $entity */
+    $entity = $this->create($values);
+    foreach ($entity as $field_name => $value) {
+      if (!in_array($field_name, $forbidden_keys)) {
+        $entity->get($field_name)->generateSampleItems();
+      }
+    }
+    return $entity;
+  }
+
+  /**
    * Initializes field values.
    *
    * @param \Drupal\Core\Entity\ContentEntityInterface $entity
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityStorageInterface.php b/core/lib/Drupal/Core/Entity/ContentEntityStorageInterface.php
index 47e058d8e1..f851723758 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityStorageInterface.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityStorageInterface.php
@@ -23,4 +23,21 @@
    */
   public function createTranslation(ContentEntityInterface $entity, $langcode, array $values = []);
 
+
+  /**
+   * Creates an entity with sample field values.
+   *
+   * @param string $bundle
+   *   The entity bundle.
+   * @param array $values
+   *   (optional) Any default values to use during generation.
+   *
+   * @return \Drupal\Core\Entity\FieldableEntityInterface
+   *   A fieldable content entity.
+   *
+   * @throws \Drupal\Core\Entity\Exception\MissingEntityBundleException
+   *   Thrown if the requested entity bundle does not exist.
+   */
+  public function createWithSampleValues($bundle, array $values = []);
+
 }
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
index 1172406e34..d19c1e184f 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
@@ -13,6 +13,7 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityStorageException;
+use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\Query\QueryInterface;
 use Drupal\Core\Entity\Schema\DynamicallyFieldableEntityStorageSchemaInterface;
@@ -133,6 +134,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
       $container->get('database'),
       $container->get('entity.manager'),
       $container->get('cache.entity'),
+      $container->get('entity_type.bundle.info'),
       $container->get('language_manager')
     );
   }
@@ -159,11 +161,13 @@ public function getFieldStorageDefinitions() {
    *   The entity manager.
    * @param \Drupal\Core\Cache\CacheBackendInterface $cache
    *   The cache backend to be used.
+   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
+   *   The entity type bundle information object.
    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
    *   The language manager.
    */
-  public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityManagerInterface $entity_manager, CacheBackendInterface $cache, LanguageManagerInterface $language_manager) {
-    parent::__construct($entity_type, $entity_manager, $cache);
+  public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityManagerInterface $entity_manager, CacheBackendInterface $cache, EntityTypeBundleInfoInterface $entity_type_bundle_info, LanguageManagerInterface $language_manager) {
+    parent::__construct($entity_type, $entity_manager, $cache, $entity_type_bundle_info);
     $this->database = $database;
     $this->languageManager = $language_manager;
     $this->initTableLayout();
diff --git a/core/lib/Drupal/Core/Field/FieldItemList.php b/core/lib/Drupal/Core/Field/FieldItemList.php
index a1a1ebdb9e..5d13a5e5cc 100644
--- a/core/lib/Drupal/Core/Field/FieldItemList.php
+++ b/core/lib/Drupal/Core/Field/FieldItemList.php
@@ -259,7 +259,7 @@ public function view($display_options = []) {
    */
   public function generateSampleItems($count = 1) {
     $field_definition = $this->getFieldDefinition();
-    $field_type_class = \Drupal::service('plugin.manager.field.field_type')->getPluginClass($field_definition->getType());
+    $field_type_class = $field_definition->getItemDefinition()->getClass();
     for ($delta = 0; $delta < $count; $delta++) {
       $values[$delta] = $field_type_class::generateSampleValue($field_definition);
     }
diff --git a/core/modules/comment/src/CommentStorage.php b/core/modules/comment/src/CommentStorage.php
index d164d8ad9e..fe9c3b1d6a 100644
--- a/core/modules/comment/src/CommentStorage.php
+++ b/core/modules/comment/src/CommentStorage.php
@@ -5,6 +5,7 @@
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
@@ -41,11 +42,13 @@ class CommentStorage extends SqlContentEntityStorage implements CommentStorageIn
    *   The current user.
    * @param \Drupal\Core\Cache\CacheBackendInterface $cache
    *   Cache backend instance to use.
+   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
+   *   The entity type bundle information object.
    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
    *   The language manager.
    */
-  public function __construct(EntityTypeInterface $entity_info, Connection $database, EntityManagerInterface $entity_manager, AccountInterface $current_user, CacheBackendInterface $cache, LanguageManagerInterface $language_manager) {
-    parent::__construct($entity_info, $database, $entity_manager, $cache, $language_manager);
+  public function __construct(EntityTypeInterface $entity_info, Connection $database, EntityManagerInterface $entity_manager, AccountInterface $current_user, CacheBackendInterface $cache, EntityTypeBundleInfoInterface $entity_type_bundle_info, LanguageManagerInterface $language_manager) {
+    parent::__construct($entity_info, $database, $entity_manager, $cache, $entity_type_bundle_info, $language_manager);
     $this->currentUser = $current_user;
   }
 
@@ -59,6 +62,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
       $container->get('entity.manager'),
       $container->get('current_user'),
       $container->get('cache.entity'),
+      $container->get('entity_type.bundle.info'),
       $container->get('language_manager')
     );
   }
diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php
index 7529532581..f254ccff93 100644
--- a/core/modules/user/src/Entity/User.php
+++ b/core/modules/user/src/Entity/User.php
@@ -9,6 +9,7 @@
 use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\user\RoleInterface;
+use Drupal\user\TimeZoneItem;
 use Drupal\user\UserInterface;
 
 /**
@@ -498,6 +499,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->addPropertyConstraints('value', [
         'AllowedValues' => ['callback' => __CLASS__ . '::getAllowedTimezones'],
       ]);
+    $fields['timezone']->getItemDefinition()->setClass(TimeZoneItem::class);
 
     $fields['status'] = BaseFieldDefinition::create('boolean')
       ->setLabel(t('User status'))
diff --git a/core/modules/user/src/TimeZoneItem.php b/core/modules/user/src/TimeZoneItem.php
new file mode 100644
index 0000000000..693d1cc2ac
--- /dev/null
+++ b/core/modules/user/src/TimeZoneItem.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\user;
+
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\Plugin\Field\FieldType\StringItem;
+use Drupal\user\Entity\User;
+
+/**
+ * Defines a custom field item class for the 'timezone' user entity field.
+ */
+class TimeZoneItem extends StringItem {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
+    $timezones = User::getAllowedTimezones();
+    // We need to vary the selected timezones since we're generating a sample.
+    $key = rand(0, count($timezones));
+    return $timezones[$key];
+  }
+
+}
diff --git a/core/modules/user/src/UserNameItem.php b/core/modules/user/src/UserNameItem.php
index 6a53eb5d06..e6a0f2d420 100644
--- a/core/modules/user/src/UserNameItem.php
+++ b/core/modules/user/src/UserNameItem.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\user;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\Plugin\Field\FieldType\StringItem;
 
 /**
@@ -23,4 +24,14 @@ public function isEmpty() {
     return $value === NULL || $value === '';
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
+    $values = parent::generateSampleValue($field_definition);
+    // User names larger than 60 characters won't pass validation.
+    $values['value'] = substr($values['value'], 0, UserInterface::USERNAME_MAX_LENGTH);
+    return $values;
+  }
+
 }
diff --git a/core/modules/user/tests/src/Kernel/UserEntityTest.php b/core/modules/user/tests/src/Kernel/UserEntityTest.php
index 1c501f049e..73fe869ec3 100644
--- a/core/modules/user/tests/src/Kernel/UserEntityTest.php
+++ b/core/modules/user/tests/src/Kernel/UserEntityTest.php
@@ -22,6 +22,14 @@ class UserEntityTest extends KernelTestBase {
   public static $modules = ['system', 'user', 'field'];
 
   /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installEntitySchema('user');
+  }
+
+  /**
    * Tests some of the methods.
    *
    * @see \Drupal\user\Entity\User::getRoles()
@@ -65,4 +73,22 @@ public function testUserMethods() {
     $this->assertEqual([RoleInterface::AUTHENTICATED_ID, 'test_role_two'], $user->getRoles());
   }
 
+  /**
+   * Tests that all user fields validate properly.
+   *
+   * @see \Drupal\Core\Field\FieldItemListInterface::generateSampleItems
+   * @see \Drupal\Core\Field\FieldItemInterface::generateSampleValue()
+   * @see \Drupal\Core\Entity\FieldableEntityInterface::validate()
+   */
+  public function testUserValidation() {
+    $user = User::create([]);
+    foreach ($user as $field_name => $field) {
+      if (!in_array($field_name, ['uid'])) {
+        $user->$field_name->generateSampleItems();
+      }
+    }
+    $violations = $user->validate();
+    $this->assertFalse((bool) $violations->count());
+  }
+
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/Element/CreateSampleEntityTest.php b/core/tests/Drupal/KernelTests/Core/Entity/Element/CreateSampleEntityTest.php
new file mode 100644
index 0000000000..513266c3d1
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Entity/Element/CreateSampleEntityTest.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Entity\Element;
+
+use Drupal\Core\Entity\FieldableEntityInterface;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\node\Entity\NodeType;
+use Drupal\taxonomy\Entity\Vocabulary;
+
+/**
+ * Tests the EntityGenerator API.
+ *
+ * @coversDefaultClass \Drupal\Core\Entity\ContentEntityStorageBase
+ * @group Entity
+ */
+class CreateSampleEntityTest extends KernelTestBase {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['system', 'field', 'filter', 'text', 'file', 'user', 'node', 'comment', 'taxonomy'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setup();
+
+    $this->installEntitySchema('file');
+    $this->installEntitySchema('user');
+    $this->installEntitySchema('node');
+    $this->installEntitySchema('node_type');
+    $this->installEntitySchema('file');
+    $this->installEntitySchema('comment');
+    $this->installEntitySchema('comment_type');
+    $this->installEntitySchema('taxonomy_vocabulary');
+    $this->installEntitySchema('taxonomy_term');
+    $this->entityTypeManager = $this->container->get('entity_type.manager');
+    NodeType::create(['type' => 'article', 'name' => 'Article'])->save();
+    NodeType::create(['type' => 'page', 'name' => 'Page'])->save();
+    Vocabulary::create(['name' => 'Tags', 'vid' => 'tags'])->save();
+  }
+
+  /**
+   * Tests generation of all enabled content entity types.
+   *
+   * * @covers ::createWithSampleValues
+   */
+  public function testGenerateContentEntity() {
+    foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $definition) {
+      if ($definition->entityClassImplements(FieldableEntityInterface::class)) {
+        // Create sample entities with bundles.
+        if ($bundle_type = $definition->getBundleEntityType()) {
+          foreach ($this->entityTypeManager->getStorage($bundle_type)->loadMultiple() as $bundle) {
+            $entity = $this->entityTypeManager->getStorage($entity_type_id)->createWithSampleValues($bundle->id());
+            $violations = $entity->validate();
+            $this->assertCount(0, $violations);
+          }
+        }
+        // Create sample entities without bundles.
+        else {
+          $entity = $this->entityTypeManager->getStorage($entity_type_id)->createWithSampleValues();
+          $violations = $entity->validate();
+          $this->assertCount(0, $violations);
+        }
+      }
+    }
+  }
+
+}
