diff --git a/core/lib/Drupal/Core/Entity/ContentEntityType.php b/core/lib/Drupal/Core/Entity/ContentEntityType.php
index f9de958..07e79f2 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityType.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityType.php
@@ -13,6 +13,13 @@
 class ContentEntityType extends EntityType implements ContentEntityTypeInterface {
 
   /**
+   * Entity constraint definitions.
+   *
+   * @var array[]
+   */
+  protected $constraints = array();
+
+  /**
    * {@inheritdoc}
    */
   public function __construct($definition) {
@@ -36,4 +43,27 @@ public function getConfigDependencyKey() {
     return 'content';
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConstraints() {
+    return $this->constraints;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setConstraints(array $constraints) {
+    $this->constraints = $constraints;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addConstraint($constraint_name, $options = NULL) {
+    $this->constraints[$constraint_name] = $options;
+    return $this;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php b/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php
index 79f0ccf..e7c791d 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php
@@ -11,4 +11,54 @@
  * Provides an interface for a content entity type and its metadata.
  */
 interface ContentEntityTypeInterface extends EntityTypeInterface {
+
+  /**
+   * Returns an array of validation constraints.
+   *
+   * See \Drupal\Core\TypedData\DataDefinitionInterface::getConstraints() for
+   * details on how constraints are defined.
+   *
+   * @return array[]
+   *   An array of validation constraint definitions, keyed by constraint name.
+   *   Each constraint definition can be used for instantiating
+   *   \Symfony\Component\Validator\Constraint objects.
+   *
+   * @see \Symfony\Component\Validator\Constraint
+   */
+  public function getConstraints();
+
+  /**
+   * Sets the array of validation constraints for the FieldItemList.
+   *
+   * NOTE: This will overwrite any previously set constraints. In most cases
+   * ContentEntityTypeInterface::addConstraint() should be used instead.
+   * See \Drupal\Core\TypedData\DataDefinitionInterface::getConstraints() for
+   * details on how constraints are defined.
+   *
+   * @param array $constraints
+   *   An array of validation constraint definitions, keyed by constraint name.
+   *   Each constraint definition can be used for instantiating
+   *   \Symfony\Component\Validator\Constraint objects.
+   *
+   * @return $this
+   *
+   * @see \Symfony\Component\Validator\Constraint
+   */
+  public function setConstraints(array $constraints);
+
+  /**
+   * Adds a validation constraint.
+   *
+   * See \Drupal\Core\TypedData\DataDefinitionInterface::getConstraints() for
+   * details on how constraints are defined.
+   *
+   * @param string $constraint_name
+   *   The name of the constraint to add, i.e. its plugin id.
+   * @param array|null $options
+   *   The constraint options as required by the constraint plugin, or NULL.
+   *
+   * @return $this
+   */
+  public function addConstraint($constraint_name, $options = NULL);
+
 }
diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
index 5c37aa9..ed049df 100644
--- a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
+++ b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
@@ -159,6 +159,7 @@ public function getDefinitions() {
    */
   public function clearCachedDefinitions() {
     if ($this->cacheBackend) {
+
       if ($this->cacheTags) {
         // Use the cache tags to clear the cache.
         Cache::invalidateTags($this->cacheTags);
diff --git a/core/modules/system/src/Tests/Entity/EntityTypeConstraintsTest.php b/core/modules/system/src/Tests/Entity/EntityTypeConstraintsTest.php
new file mode 100644
index 0000000..eddd25a
--- /dev/null
+++ b/core/modules/system/src/Tests/Entity/EntityTypeConstraintsTest.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\system\Tests\Entity\EntityTypeConstraintsTest.
+ */
+
+namespace Drupal\system\Tests\Entity;
+
+use Drupal\system\Tests\TypedData;
+
+/**
+ * Tests entity level validation constraints.
+ *
+ * @group Entity
+ */
+class EntityTypeConstraintsTest extends EntityUnitTestBase {
+
+  /**
+   * Tests defining entity constraints via entity type annotations and hooks.
+   */
+  public function testConstraintDefinition() {
+    // Test reading the annotation.
+    $entity_type = $this->entityManager->getDefinition('entity_test_constraints');
+    $default_constraints = ['EntityChanged' => []];
+    $this->assertEqual($default_constraints, $entity_type->getConstraints());
+
+    // Enable our test module and test extending constraints.
+    $this->enableModules(array_merge(static::$modules, ['entity_test_constraints']));
+    $this->container->get('module_handler')->resetImplementations();
+
+    $extra_constraints = ['Test' => []];
+    $this->state->set('entity_test_constraints.build', $extra_constraints);
+    // Re-fetch the entity manager from the new container built after the new
+    // modules were enabled.
+    $this->entityManager = $this->container->get('entity.manager');
+    $this->entityManager->clearCachedDefinitions();
+    $entity_type = $this->entityManager->getDefinition('entity_test_constraints');
+    $this->assertEqual($default_constraints + $extra_constraints, $entity_type->getConstraints());
+
+    // Test altering constraints.
+    $altered_constraints = ['Test' => [ 'some_setting' => TRUE]];
+    $this->state->set('entity_test_constraints.alter', $altered_constraints);
+    // Clear the cache in state instance in the Drupal container, so it can pick
+    // up the modified value.
+    \Drupal::state()->resetCache();
+    $this->entityManager->clearCachedDefinitions();
+    $entity_type = $this->entityManager->getDefinition('entity_test_constraints');
+    $this->assertEqual($altered_constraints, $entity_type->getConstraints());
+  }
+
+}
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestConstraints.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestConstraints.php
new file mode 100644
index 0000000..b7e6ae4
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestConstraints.php
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity_test\Entity\EntityTestConstraints.
+ */
+
+namespace Drupal\entity_test\Entity;
+
+/**
+ * Defines a test class for testing the definition of entity level constraints.
+ *
+ * @ContentEntityType(
+ *   id = "entity_test_constraints",
+ *   label = @Translation("Test entity constraints"),
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "uuid" = "uuid",
+ *     "bundle" = "type",
+ *     "label" = "name"
+ *   },
+ *   base_table = "entity_test",
+ *   persistent_cache = FALSE,
+ *   constraints = {
+ *     "EntityChanged" = {}
+ *   }
+ * )
+ */
+class EntityTestConstraints extends EntityTest {
+
+}
diff --git a/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.info.yml b/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.info.yml
new file mode 100644
index 0000000..5b08087
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.info.yml
@@ -0,0 +1,8 @@
+name: 'Entity constraints test module'
+type: module
+description: 'Tests extending and altering entity constraints.'
+package: Testing
+version: VERSION
+core: 8.x
+dependencies:
+  - entity_test
diff --git a/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.module b/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.module
new file mode 100644
index 0000000..684ffb3
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.module
@@ -0,0 +1,26 @@
+<?php
+
+/**
+ * @file
+ * Test module file.
+ */
+
+/**
+ * Implements hook_entity_type_build().
+ */
+function entity_test_constraints_entity_type_build(array &$entity_types) {
+  if ($extra = \Drupal::state()->get('entity_test_constraints.build')) {
+    foreach ($extra as $id => $option) {
+      $entity_types['entity_test_constraints']->addConstraint($id, $option);
+    }
+  }
+}
+
+/**
+ * Implements hook_entity_type_alter().
+ */
+function entity_test_constraints_entity_type_alter(array &$entity_types) {
+  if ($alter = \Drupal::state()->get('entity_test_constraints.alter')) {
+    $entity_types['entity_test_constraints']->setConstraints($alter);
+  }
+}
diff --git a/core/tests/Drupal/Tests/Core/Entity/ContentEntityTypeTest.php b/core/tests/Drupal/Tests/Core/Entity/ContentEntityTypeTest.php
new file mode 100644
index 0000000..631b941
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Entity/ContentEntityTypeTest.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Entity\ContentEntityTypeTest.
+ */
+
+namespace Drupal\Tests\Core\Entity;
+
+use Drupal\Core\Entity\ContentEntityType;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Entity\ContentEntityType
+ * @group Entity
+ */
+class ContentEntityTypeTest extends UnitTestCase {
+
+  /**
+   * Sets up a ContentEntityType object for a given set of values.
+   *
+   * @param array $definition
+   *   An array of values to use for the ContentEntityType.
+   *
+   * @return \Drupal\Core\Entity\ContentEntityTypeInterface
+   */
+  protected function setUpContentEntityType($definition) {
+    if (!isset($definition['id'])) {
+      $definition += array(
+        'id' => 'example_content_entity_type',
+      );
+    }
+    return new ContentEntityType($definition);
+  }
+
+  /**
+   * Tests the constraint methods.
+   *
+   * @covers ::getConstraints
+   * @covers ::setConstraints
+   * @covers ::addConstraint
+   */
+  public function testConstraintMethods() {
+    $definition = [
+      'constraints' => [
+        'EntityChanged' => [],
+      ],
+    ];
+    $entity_type = $this->setUpContentEntityType($definition);
+    $this->assertEquals($definition['constraints'], $entity_type->getConstraints());
+    $entity_type->addConstraint('Test');
+    $this->assertEquals($definition['constraints'] + ['Test' => NULL], $entity_type->getConstraints());
+    $entity_type->setConstraints([]);
+    $this->assertEquals([], $entity_type->getConstraints());
+  }
+
+}
