diff --git a/core/includes/install.inc b/core/includes/install.inc
index 42b0d40..9540315 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -958,6 +958,7 @@ function drupal_check_module($module) {
   module_load_install($module);
   // Check requirements
   $requirements = \Drupal::moduleHandler()->invoke($module, 'requirements', array('install'));
+  \Drupal::moduleHandler()->alter('requirements', $requirements, $module);
   if (is_array($requirements) && drupal_requirements_severity($requirements) == REQUIREMENT_ERROR) {
     // Print any error messages
     foreach ($requirements as $requirement) {
diff --git a/core/includes/update.inc b/core/includes/update.inc
index 683e7fe..e116a5d 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -97,6 +97,7 @@ function update_system_schema_requirements() {
 function update_check_requirements() {
   // Check requirements of all loaded modules.
   $requirements = \Drupal::moduleHandler()->invokeAll('requirements', array('update'));
+  \Drupal::moduleHandler()->alter('requirements', $requirements);
   $requirements += update_system_schema_requirements();
   return $requirements;
 }
diff --git a/core/modules/system/src/Tests/Module/HookRequirementsTest.php b/core/modules/system/src/Tests/Module/HookRequirementsTest.php
index 83fdce9..d37b7f2 100644
--- a/core/modules/system/src/Tests/Module/HookRequirementsTest.php
+++ b/core/modules/system/src/Tests/Module/HookRequirementsTest.php
@@ -28,4 +28,36 @@ function testHookRequirementsFailure() {
     $this->assertText(t('Requirements 1 Test failed requirements'), 'Modules status has been updated.');
     $this->assertModules(array('requirements1_test'), FALSE);
   }
+
+  /**
+   * Assert that a module cannot be installed if composer dependencies are not
+   * installed.
+   */
+  function testComposerDependenciesFailure() {
+    $this->assertModules(['composer_uninstallable'], FALSE);
+
+    // Attempt to install the composer_uninstallable module.
+    $edit = [];
+    $edit['modules[Testing][composer_uninstallable][enable]'] = 'composer_uninstallable';
+    $this->drupalPostForm('admin/modules', $edit, t('Install'));
+
+    // Makes sure the module was NOT installed.
+    $this->assertModules(['composer_uninstallable'], FALSE);
+  }
+
+  /**
+   * Assert that a module cannot be installed if composer dependencies that are
+   * already installed.
+   */
+  function testComposerDependenciesSuccess() {
+    $this->assertModules(['composer_installable'], FALSE);
+
+    // Attempt to install the composer_uninstallable module.
+    $edit = [];
+    $edit['modules[Testing][composer_installable][enable]'] = 'composer_uninstallable';
+    $this->drupalPostForm('admin/modules', $edit, t('Install'));
+
+    // Makes sure the module was NOT installed.
+    $this->assertModules(['composer_installable'], TRUE);
+  }
 }
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index a8cc12d..6c32d0b 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -482,6 +482,66 @@ function system_updater_info() {
 }
 
 /**
+ * Implements hook_requirements_alter().
+ *
+ * @param array $requirements
+ *   requirements array already provided by hook_requirements
+ * @param string $module
+ *   module name
+ */
+function system_requirements_alter(array &$requirements = [], $module) {
+
+  if (!isset($requirements['composer_dependencies'])) {
+    $requirements['composer_dependencies'] = [
+      'description' => t('All composer dependencies have been installed.'),
+      'severity' => REQUIREMENT_OK,
+      'value' => t('Never run'),
+      'title' => $module,
+    ];
+  }
+
+  $module_dir = drupal_get_path('module', $module);
+
+  // Check if the modules that are going to be installed have a composer.json
+  // file, if they have one, make sure that the configured dependencies are
+  // installed. If failures are detected, make sure the dependent modules
+  // aren't installed either.
+  if (file_exists($module_dir . '/composer.json')) {
+
+    $composer = json_decode(file_get_contents($module_dir . '/composer.json'));
+    $composer_dependencies = $composer->require;
+
+    $composer_lock = json_decode(file_get_contents(DRUPAL_ROOT . '/core/composer.lock'));
+    $installed_packages = $composer_lock->packages;
+
+    // Loop over all required packages and check if the package is already
+    // installed.
+    $dependencies_installed = [];
+    foreach ($composer_dependencies as $package_name => $version_requirement) {
+      foreach ($installed_packages as $installed_package) {
+        if ($package_name == $installed_package->name) {
+          $dependencies_installed[] = true;
+        }
+      }
+    }
+
+    // Not all required packages are installed so don't install the module.
+    if (count($dependencies_installed) < count($composer_dependencies)) {
+      $requirements['composer_dependencies'] = [
+        'description' => t('Not all the modules have their composer dependencies installed yet. Please find more information on <a href="@handbook">this handbook page</a>.',
+          [
+            '!handbook' => 'https://www.drupal.org/node/2494073'
+          ]),
+        'severity' => REQUIREMENT_ERROR,
+        'value' => t('Never run'),
+        'title' => $module,
+      ];
+    }
+  }
+
+}
+
+/**
  * Implements hook_filetransfer_info().
  */
 function system_filetransfer_info() {
diff --git a/core/modules/system/tests/modules/composer_installable/composer.json b/core/modules/system/tests/modules/composer_installable/composer.json
new file mode 100644
index 0000000..a7c2267
--- /dev/null
+++ b/core/modules/system/tests/modules/composer_installable/composer.json
@@ -0,0 +1,6 @@
+{
+    "name": "drupal_test/composer_installable",
+    "require": {
+      "psr/log": "~1.0"
+    }
+}
diff --git a/core/modules/system/tests/modules/composer_installable/composer_installable.info.yml b/core/modules/system/tests/modules/composer_installable/composer_installable.info.yml
new file mode 100644
index 0000000..399e267
--- /dev/null
+++ b/core/modules/system/tests/modules/composer_installable/composer_installable.info.yml
@@ -0,0 +1,6 @@
+name: 'Composer Installable'
+type: module
+description: 'Test module that is installable because its composer dependencies have already been installed'
+package: Testing
+version: VERSION
+core: 8.x
diff --git a/core/modules/system/tests/modules/composer_uninstallable/composer.json b/core/modules/system/tests/modules/composer_uninstallable/composer.json
new file mode 100644
index 0000000..9bbd8ff
--- /dev/null
+++ b/core/modules/system/tests/modules/composer_uninstallable/composer.json
@@ -0,0 +1,6 @@
+{
+    "name": "drupal_test/composer_uninstallable",
+    "require": {
+        "scalopus/empty": "^1.1"
+    }
+}
diff --git a/core/modules/system/tests/modules/composer_uninstallable/composer_uninstallable.info.yml b/core/modules/system/tests/modules/composer_uninstallable/composer_uninstallable.info.yml
new file mode 100644
index 0000000..a7f734e
--- /dev/null
+++ b/core/modules/system/tests/modules/composer_uninstallable/composer_uninstallable.info.yml
@@ -0,0 +1,6 @@
+name: 'Composer Uninstallable'
+type: module
+description: 'Test module that is not installable because of missing composer dependencies.'
+package: Testing
+version: VERSION
+core: 8.x
