diff --git a/core/core.services.yml b/core/core.services.yml
index 1d3ee43050957ed77d128fd0f30ca5d6987bc1e1..895b3845b0166142498f3620ddf81ce5dc9e1f05 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -144,6 +144,9 @@ services:
   plugin.manager.entity:
     class: Drupal\Core\Entity\EntityManager
     arguments: ['%container.namespaces%']
+  plugin.manager.archiver:
+    class: Drupal\Core\Archiver\ArchiverManager
+    arguments: ['%container.namespaces%']
   request:
     class: Symfony\Component\HttpFoundation\Request
   event_dispatcher:
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 617d27b02fb1dc1601351e9bf3b080725a46096e..0e824a013c978080b54da720e54d336c9f0c3ab2 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -6523,32 +6523,6 @@ function drupal_check_incompatibility($v, $current_version) {
   }
 }
 
-/**
- * Retrieves a list of all available archivers.
- *
- * @see hook_archiver_info()
- * @see hook_archiver_info_alter()
- */
-function archiver_get_info() {
-  $archiver_info = &drupal_static(__FUNCTION__, array());
-
-  if (empty($archiver_info)) {
-    $cache = cache()->get('archiver_info');
-    if ($cache === FALSE) {
-      // Rebuild the cache and save it.
-      $archiver_info = module_invoke_all('archiver_info');
-      drupal_alter('archiver_info', $archiver_info);
-      uasort($archiver_info, 'drupal_sort_weight');
-      cache()->set('archiver_info', $archiver_info);
-    }
-    else {
-      $archiver_info = $cache->data;
-    }
-  }
-
-  return $archiver_info;
-}
-
 /**
  * Returns a string of supported archive extensions.
  *
@@ -6558,7 +6532,7 @@ function archiver_get_info() {
  */
 function archiver_get_extensions() {
   $valid_extensions = array();
-  foreach (archiver_get_info() as $archive) {
+  foreach (Drupal::service('plugin.manager.archiver')->getDefinitions() as $archive) {
     foreach ($archive['extensions'] as $extension) {
       foreach (explode('.', $extension) as $part) {
         if (!in_array($part, $valid_extensions)) {
@@ -6588,20 +6562,7 @@ function archiver_get_archiver($file) {
   if (!is_file($filepath)) {
     throw new Exception(t('Archivers can only operate on local files: %file not supported', array('%file' => $file)));
   }
-  $archiver_info = archiver_get_info();
-
-  foreach ($archiver_info as $implementation) {
-    foreach ($implementation['extensions'] as $extension) {
-      // Because extensions may be multi-part, such as .tar.gz,
-      // we cannot use simpler approaches like substr() or pathinfo().
-      // This method isn't quite as clean but gets the job done.
-      // Also note that the file may not yet exist, so we cannot rely
-      // on fileinfo() or other disk-level utilities.
-      if (strrpos($filepath, '.' . $extension) === strlen($filepath) - strlen('.' . $extension)) {
-        return new $implementation['class']($filepath);
-      }
-    }
-  }
+  return Drupal::service('plugin.manager.archiver')->getInstance(array('filepath' => $filepath));
 }
 
 /**
diff --git a/core/lib/Drupal/Core/Archiver/ArchiverManager.php b/core/lib/Drupal/Core/Archiver/ArchiverManager.php
new file mode 100644
index 0000000000000000000000000000000000000000..38851469d693dc6a5c19f7c7eaf3cd8b0694426f
--- /dev/null
+++ b/core/lib/Drupal/Core/Archiver/ArchiverManager.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * Contains \Drupal\Core\Archiver\ArchiverManager.
+ */
+
+namespace Drupal\Core\Archiver;
+
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Core\Plugin\Discovery\AlterDecorator;
+use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
+use Drupal\Core\Plugin\Discovery\CacheDecorator;
+
+/**
+ * Archiver plugin manager.
+ */
+class ArchiverManager extends PluginManagerBase {
+
+  /**
+   * Constructs a ArchiverManager object.
+   *
+   * @param array $namespaces
+   *   An array of paths keyed by its corresponding namespaces.
+   */
+  public function __construct(array $namespaces) {
+    $this->discovery = new AnnotatedClassDiscovery('Core', 'Archiver', $namespaces);
+    $this->discovery = new AlterDecorator($this->discovery, 'archiver_info');
+    $this->discovery = new CacheDecorator($this->discovery, 'archiver_info');
+  }
+
+  /**
+   * Overrides \Drupal\Component\Plugin\PluginManagerBase::createInstance().
+   */
+  public function createInstance($plugin_id, array $configuration = array()) {
+    $plugin_definition = $this->discovery->getDefinition($plugin_id);
+    $plugin_class = DefaultFactory::getPluginClass($plugin_id, $plugin_definition);
+    return new $plugin_class($configuration['filepath']);
+  }
+
+  /**
+   * Implements \Drupal\Core\PluginManagerInterface::getInstance().
+   */
+  public function getInstance(array $options) {
+    $filepath = $options['filepath'];
+    foreach ($this->getDefinitions() as $plugin_id => $definition) {
+      foreach ($definition['extensions'] as $extension) {
+        // Because extensions may be multi-part, such as .tar.gz,
+        // we cannot use simpler approaches like substr() or pathinfo().
+        // This method isn't quite as clean but gets the job done.
+        // Also note that the file may not yet exist, so we cannot rely
+        // on fileinfo() or other disk-level utilities.
+        if (strrpos($filepath, '.' . $extension) === strlen($filepath) - strlen('.' . $extension)) {
+          return $this->createInstance($plugin_id, $options);
+        }
+      }
+    }
+  }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Plugin/Core/Archiver/Tar.php b/core/modules/system/lib/Drupal/system/Plugin/Core/Archiver/Tar.php
new file mode 100644
index 0000000000000000000000000000000000000000..b582804a866d4948acd33ff4f1eab245f51d50a9
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Plugin/Core/Archiver/Tar.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Plugin\Core\Archiver\Tar.
+ */
+
+namespace Drupal\system\Plugin\Core\Archiver;
+
+use Drupal\Component\Archiver\Tar as BaseTar;
+use Drupal\Component\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+
+/**
+ * Defines a archiver implementation for .tar files.
+ *
+ * @Plugin(
+ *   id = "Tar",
+ *   title = @Translation("Tar"),
+ *   description = @Translation("Handles .tar files."),
+ *   extensions = {"tar", "tgz", "tar.gz", "tar.bz2"}
+ * )
+ */
+class Tar extends BaseTar {
+}
diff --git a/core/modules/system/lib/Drupal/system/Plugin/Core/Archiver/Zip.php b/core/modules/system/lib/Drupal/system/Plugin/Core/Archiver/Zip.php
new file mode 100644
index 0000000000000000000000000000000000000000..277d369276e065c0310501d861ae3440d45675b0
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Plugin/Core/Archiver/Zip.php
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Plugin\Core\Archiver\Zip.
+ */
+
+namespace Drupal\system\Plugin\Core\Archiver;
+
+use Drupal\Component\Archiver\Zip as BaseZip;
+use Drupal\Component\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+
+/**
+ * Defines a archiver implementation for .zip files.
+ *
+ * @link http://php.net/zip
+ *
+ * @Plugin(
+ *   id = "Zip",
+ *   title = @Translation("Zip"),
+ *   description = @Translation("Handles zip files."),
+ *   extensions = {"zip"}
+ * )
+ */
+class Zip extends BaseZip {
+}
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 83f4587840dd0404166489f71afb0416dd028f33..13aa535ad89c47141323f6c84857568ce24cca3b 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -3098,33 +3098,6 @@ function hook_file_mimetype_mapping_alter(&$mapping) {
   $mapping['extensions']['ogg'] = 189;
 }
 
-/**
- * Declare archivers to the system.
- *
- * An archiver is a class that is able to package and unpackage one or more files
- * into a single possibly compressed file.  Common examples of such files are
- * zip files and tar.gz files.  All archiver classes must implement
- * ArchiverInterface.
- *
- * Each entry should be keyed on a unique value, and specify three
- * additional keys:
- * - class: The name of the PHP class for this archiver.
- * - extensions: An array of file extensions that this archiver supports.
- * - weight: This optional key specifies the weight of this archiver.
- *   When mapping file extensions to archivers, the first archiver by
- *   weight found that supports the requested extension will be used.
- *
- * @see hook_archiver_info_alter()
- */
-function hook_archiver_info() {
-  return array(
-    'tar' => array(
-      'class' => 'Drupal\Component\Archiver\Tar',
-      'extensions' => array('tar', 'tar.gz', 'tar.bz2'),
-    ),
-  );
-}
-
 /**
  * Alter archiver information declared by other modules.
  *
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index b3f9bc17347e852b10d276863a7afde2f13cfe8b..ebe55483f238ec71bd4466098c48b7f92439f1f7 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -3889,23 +3889,6 @@ function system_date_format_delete($date_format_id) {
   }
 }
 
-/**
- * Implements hook_archiver_info().
- */
-function system_archiver_info() {
-  $archivers['tar'] = array(
-    'class' => 'Drupal\Component\Archiver\Tar',
-    'extensions' => array('tar', 'tgz', 'tar.gz', 'tar.bz2'),
-  );
-  if (function_exists('zip_open')) {
-    $archivers['zip'] = array(
-      'class' => 'Drupal\Component\Archiver\Zip',
-      'extensions' => array('zip'),
-    );
-  }
-  return $archivers;
-}
-
 /**
  * Returns HTML for a confirmation form.
  *
diff --git a/core/modules/update/tests/modules/update_test/update_test.module b/core/modules/update/tests/modules/update_test/update_test.module
index edc7aa4270fa5fa9722123ff9f208208943afdb4..31ee72dc4b5de96bb097608ce479f817ec7b2508 100644
--- a/core/modules/update/tests/modules/update_test/update_test.module
+++ b/core/modules/update/tests/modules/update_test/update_test.module
@@ -136,15 +136,15 @@ function update_test_mock_page($project_name) {
 }
 
 /**
- * Implements hook_archiver_info().
+ * Implements hook_archiver_info_alter().
  */
-function update_test_archiver_info() {
-  return array(
-    'update_test_archiver' => array(
-      // This is bogus, we only care about the extensions for now.
-      'class' => 'Drupal\Component\Archiver\UpdateTest',
-      'extensions' => array('update-test-extension'),
-    ),
+function update_test_archiver_info_alter(&$definitions) {
+  // We only care about the extensions for now and the only way to add a new
+  // extension without a class is via alter. This definition is bogus, real
+  // archivers have a class and the definition goes in the annotation of the
+  // class.
+  $definitions['update_test_archiver'] = array(
+    'extensions' => array('update-test-extension'),
   );
 }