diff --git a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
index 515db0d2f6d3aa249dcea2a9a75bf6eb7d07fb70..d5c9c680f90ff0cc6da3ec18588b9c8c072e73c3 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
@@ -79,6 +79,40 @@ protected function doCreate(array $values) {
     return $entity;
   }
 
+  /**
+   * {@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->entityManager->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, TRUE)) {
+        $entity->get($field_name)->generateSampleItems();
+      }
+    }
+    return $entity;
+  }
+
   /**
    * Initializes field values.
    *
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityStorageInterface.php b/core/lib/Drupal/Core/Entity/ContentEntityStorageInterface.php
index 47e058d8e1b557fd185c1a847e46f3fdfa6146a2..eb979c7fd6a508ba3782e0b8cdb79a210d017ebf 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityStorageInterface.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityStorageInterface.php
@@ -23,4 +23,21 @@ interface ContentEntityStorageInterface extends EntityStorageInterface {
    */
   public function createTranslation(ContentEntityInterface $entity, $langcode, array $values = []);
 
+
+  /**
+   * Creates an entity with sample field values.
+   *
+   * @param string|bool $bundle
+   *   (optional) 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\EntityStorageException
+   *   Thrown if the bundle does not exist or was needed but not specified.
+   */
+  public function createWithSampleValues($bundle = FALSE, array $values = []);
+
 }
diff --git a/core/lib/Drupal/Core/Entity/KeyValueStore/KeyValueContentEntityStorage.php b/core/lib/Drupal/Core/Entity/KeyValueStore/KeyValueContentEntityStorage.php
index c42e7c0de5430c015f57037fc1046001a11623ac..b3fc12d6b61b8653f043284a782f3411af455600 100644
--- a/core/lib/Drupal/Core/Entity/KeyValueStore/KeyValueContentEntityStorage.php
+++ b/core/lib/Drupal/Core/Entity/KeyValueStore/KeyValueContentEntityStorage.php
@@ -18,4 +18,9 @@ public function createTranslation(ContentEntityInterface $entity, $langcode, arr
     //   https://www.drupal.org/node/2618436.
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function createWithSampleValues($bundle = FALSE, array $values = []) {}
+
 }
diff --git a/core/lib/Drupal/Core/Field/FieldItemList.php b/core/lib/Drupal/Core/Field/FieldItemList.php
index a1a1ebdb9ebb12c02e3789471d6de1becb1c79ac..5d13a5e5cc61a8c6fe690bbe5c6283936a643137 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/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php
index 7529532581e9ee847dee6789f214c800dba3b5bc..f254ccff9377326ed21b6036073b3ce5dfdbc0af 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 0000000000000000000000000000000000000000..f109691575bf3b66c08c5d98915659debdb23401
--- /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) - 1);
+    return $timezones[$key];
+  }
+
+}
diff --git a/core/modules/user/src/UserNameItem.php b/core/modules/user/src/UserNameItem.php
index 6a53eb5d0629c38588ce33a5959e83a412d26e94..e6a0f2d4209db3440453b818c0792194fd705167 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 1c501f049e705ba24eb25e985e1368c84cef4d5a..73fe869ec3d41bdfeb38858db1282b523507780e 100644
--- a/core/modules/user/tests/src/Kernel/UserEntityTest.php
+++ b/core/modules/user/tests/src/Kernel/UserEntityTest.php
@@ -21,6 +21,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.
    *
@@ -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/CreateSampleEntityTest.php b/core/tests/Drupal/KernelTests/Core/Entity/CreateSampleEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b5bcd487f2fdb340add1a564248cf0c076237797
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Entity/CreateSampleEntityTest.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Entity;
+
+use Drupal\Core\Entity\FieldableEntityInterface;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\node\Entity\NodeType;
+use Drupal\taxonomy\Entity\Vocabulary;
+
+/**
+ * Tests the ContentEntityStorageBase::createWithSampleValues method.
+ *
+ * @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 sample value content entity creation of all types.
+   *
+   * @covers ::createWithSampleValues
+   */
+  public function testSampleValueContentEntity() {
+    foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $definition) {
+      if ($definition->entityClassImplements(FieldableEntityInterface::class)) {
+        $label = $definition->getKey('label');
+        $values = [];
+        if ($label) {
+          $title = $this->randomString();
+          $values[$label] = $title;
+        }
+        // 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(), $values);
+            $violations = $entity->validate();
+            $this->assertCount(0, $violations);
+            if ($label) {
+              $this->assertEquals($title, $entity->label());
+            }
+          }
+        }
+        // Create sample entities without bundles.
+        else {
+          $entity = $this->entityTypeManager->getStorage($entity_type_id)->createWithSampleValues(FALSE, $values);
+          $violations = $entity->validate();
+          $this->assertCount(0, $violations);
+          if ($label) {
+            $this->assertEquals($title, $entity->label());
+          }
+        }
+      }
+    }
+  }
+
+}