diff --git a/core/lib/Drupal/Core/Extension/Requirement/Requirement.php b/core/lib/Drupal/Core/Extension/Requirement/Requirement.php
new file mode 100644
index 0000000000..722c153aa5
--- /dev/null
+++ b/core/lib/Drupal/Core/Extension/Requirement/Requirement.php
@@ -0,0 +1,158 @@
+<?php
+
+namespace Drupal\Core\Extension\Requirement;
+
+/**
+ * Provides a Requirement value object.
+ */
+class Requirement implements \ArrayAccess {
+
+  const PHASE_INSTALL = 'install';
+
+  const PHASE_UPDATE = 'update';
+
+  const PHASE_RUNTIME = 'runtime';
+
+  const SEVERITY_INFO = -1;
+
+  const SEVERITY_OK = 0;
+
+  const SEVERITY_WARNING = 1;
+
+  const SEVERITY_ERROR = 2;
+
+  /**
+   * The requirement definition.
+   *
+   * @var array
+   */
+  protected $definition = [];
+
+  /**
+   * Construct a new requirement object.
+   *
+   * @param array $values
+   *   (optional) If given, an array of initial values to set on the definition.
+   */
+  public function __construct(array $values = []) {
+    $this->definition = $values;
+  }
+
+  /**
+   * Create a new requirement.
+   *
+   * @return static
+   *   A new requirementDefinition object.
+   */
+  public static function create() {
+    $definition = [];
+    return new static($definition);
+  }
+
+  /**
+   * Set the title of the requirement.
+   *
+   * @param string $title
+   *   The title.
+   *
+   * @return static
+   *   The object itself for chaining.
+   */
+  public function setTitle($title) {
+    $this->definition['title'] = $title;
+    return $this;
+  }
+
+  /**
+   * Set the current value (e.g., version, time, level, etc).
+   *
+   * During install phase, this should only be used for version numbers, do not
+   * set it if not applicable.
+   *
+   * @param string $value
+   *   The current value.
+   *
+   * @return static
+   *   The object itself for chaining.
+   */
+  public function setValue($value) {
+    $this->definition['value'] = $value;
+    return $this;
+  }
+
+  /**
+   * Set the description of the requirement/status.
+   *
+   * @param string $description
+   *   The description.
+   *
+   * @return static
+   *   The object itself for chaining.
+   */
+  public function setDescription($description) {
+    $this->definition['description'] = $description;
+    return $this;
+  }
+
+  /**
+   * Set the requirement's result/severity level.
+   *
+   * Must be one of:
+   *   - REQUIREMENT_INFO: For info only.
+   *   - REQUIREMENT_OK: The requirement is satisfied.
+   *   - REQUIREMENT_WARNING: The requirement failed with a warning.
+   *   - REQUIREMENT_ERROR: The requirement failed with an error.
+   *
+   * @param string $severity
+   *   The severity.
+   *
+   * @return static
+   *   The object itself for chaining.
+   */
+  public function setSeverity($severity) {
+    $this->definition['severity'] = $severity;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * This is for BC support only.
+   */
+  public function offsetExists($offset) {
+    // PHP's array access does not work correctly with isset(), so we have to
+    // bake isset() in here. See https://bugs.php.net/bug.php?id=41727.
+    return array_key_exists($offset, $this->definition) && isset($this->definition[$offset]);
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * This is for BC support only.
+   */
+  public function &offsetGet($offset) {
+    if (!isset($this->definition[$offset])) {
+      $this->definition[$offset] = NULL;
+    }
+    return $this->definition[$offset];
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * This is for BC support only.
+   */
+  public function offsetSet($offset, $value) {
+    $this->definition[$offset] = $value;
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * This is for BC support only.
+   */
+  public function offsetUnset($offset) {
+    unset($this->definition[$offset]);
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Extension/Requirement/RequirementTest.php b/core/tests/Drupal/Tests/Core/Extension/Requirement/RequirementTest.php
new file mode 100644
index 0000000000..b4b6beb8a4
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Extension/Requirement/RequirementTest.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Drupal\Tests\Core\Extension\Requirement;
+
+use Drupal\Core\Extension\Requirement\Requirement;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Extension\Requirement\Requirement
+ *
+ * @group Extension
+ */
+class RequirementTest extends UnitTestCase {
+
+  /**
+   * @covers ::create
+   */
+  public function testCreate() {
+    $requirement = Requirement::create()
+      ->setTitle("Alice in Wonderland")
+      ->setDescription("It's no use going back to yesterday, because I was a different person then.")
+      ->setValue("small")
+      ->setSeverity(Requirement::SEVERITY_WARNING);
+
+    // Test array access.
+    $this->assertEquals("Alice in Wonderland", $requirement['title']);
+    $this->assertEquals("It's no use going back to yesterday, because I was a different person then.", $requirement['description']);
+    $this->assertEquals("small", $requirement['value']);
+    $this->assertEquals(Requirement::SEVERITY_WARNING, $requirement['severity']);
+  }
+
+}
