diff --git a/core/lib/Drupal/Component/Annotation/Plugin.php b/core/lib/Drupal/Component/Annotation/Plugin.php
index 115e94b77a60c1d5fb057fbae4ad04b4bb6c4634..044043410d8972f1e42fa018fac951aeda317cd6 100644
--- a/core/lib/Drupal/Component/Annotation/Plugin.php
+++ b/core/lib/Drupal/Component/Annotation/Plugin.php
@@ -18,6 +18,8 @@
  * of a class to be located with the class itself, rather than in module-based
  * info hooks.
  *
+ * @ingroup plugin_api
+ *
  * @Annotation
  */
 class Plugin implements AnnotationInterface {
diff --git a/core/lib/Drupal/Component/Plugin/ConfigurablePluginInterface.php b/core/lib/Drupal/Component/Plugin/ConfigurablePluginInterface.php
index 23311b6d06931d2e0446b640c7856a4960dbb349..2b095c1e1cc2a70c8d9b88327598745dd3b955ed 100644
--- a/core/lib/Drupal/Component/Plugin/ConfigurablePluginInterface.php
+++ b/core/lib/Drupal/Component/Plugin/ConfigurablePluginInterface.php
@@ -9,6 +9,8 @@
 
 /**
  * Provides an interface for a configurable plugin.
+ *
+ * @ingroup plugin_api
  */
 interface ConfigurablePluginInterface {
 
diff --git a/core/lib/Drupal/Component/Plugin/ContextAwarePluginInterface.php b/core/lib/Drupal/Component/Plugin/ContextAwarePluginInterface.php
index 2d1aa8a6b67b164f95019cd51055bfd05e8662ab..f29119da6f8f1980f617d60fb2827ad0359c5551 100644
--- a/core/lib/Drupal/Component/Plugin/ContextAwarePluginInterface.php
+++ b/core/lib/Drupal/Component/Plugin/ContextAwarePluginInterface.php
@@ -14,6 +14,8 @@
  *
  * Context aware plugins can specify an array of context definitions keyed by
  * context name at the plugin definition under the "context" key.
+ *
+ * @ingroup plugin_api
  */
 interface ContextAwarePluginInterface extends PluginInspectionInterface {
 
diff --git a/core/lib/Drupal/Component/Plugin/Derivative/DerivativeInterface.php b/core/lib/Drupal/Component/Plugin/Derivative/DerivativeInterface.php
index b32438fd675a73b21d2224b81259411da2fc09b4..e4b92b0a1e5df46092dc9dac0c57c156f902a088 100644
--- a/core/lib/Drupal/Component/Plugin/Derivative/DerivativeInterface.php
+++ b/core/lib/Drupal/Component/Plugin/Derivative/DerivativeInterface.php
@@ -9,6 +9,8 @@
 
 /**
  * Plugin interface for derivative plugin handling.
+ *
+ * @ingroup plugin_api
  */
 interface DerivativeInterface {
 
diff --git a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
index d7e0798e45d0d4a3677c86f72c30e6b73f1408d1..5b44bf93bfce06bf2e5fad1e1e72d640a8c7f4ca 100644
--- a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
+++ b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
@@ -10,6 +10,8 @@
 /**
  * An interface defining the minimum requirements of building a plugin
  * discovery component.
+ *
+ * @ingroup plugin_api
  */
 interface DiscoveryInterface {
 
diff --git a/core/lib/Drupal/Component/Plugin/PluginBag.php b/core/lib/Drupal/Component/Plugin/PluginBag.php
index 9631e22cc0c1c7e0e698b2d94f7cfa67e5617808..2625201a9c827da98c96966444658fa87e478db1 100644
--- a/core/lib/Drupal/Component/Plugin/PluginBag.php
+++ b/core/lib/Drupal/Component/Plugin/PluginBag.php
@@ -9,6 +9,8 @@
 
 /**
  * Defines an object which stores multiple plugin instances to lazy load them.
+ *
+ * @ingroup plugin_api
  */
 abstract class PluginBag implements \Iterator, \Countable {
 
diff --git a/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php b/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php
index 925c01565275f81782a3c5c2aeb0ac49cfe842a3..64a196c29cb818e75525095c686ca680e4e77e24 100644
--- a/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php
+++ b/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php
@@ -11,6 +11,8 @@
  *
  * This interface provides some simple tools for code receiving a plugin to
  * interact with the plugin system.
+ *
+ * @ingroup plugin_api
  */
 interface PluginInspectionInterface {
 
diff --git a/core/lib/Drupal/Component/Plugin/PluginManagerInterface.php b/core/lib/Drupal/Component/Plugin/PluginManagerInterface.php
index ec82dc35e6a1f5f980be94cad426ca8523575885..803682a321e677ee5f2505314bbf4af791df49b2 100644
--- a/core/lib/Drupal/Component/Plugin/PluginManagerInterface.php
+++ b/core/lib/Drupal/Component/Plugin/PluginManagerInterface.php
@@ -26,6 +26,8 @@
  * class, which contains the proxying logic.
  *
  * @see \Drupal\Component\Plugin\PluginManagerBase
+ *
+ * @ingroup plugin_api
  */
 interface PluginManagerInterface extends DiscoveryInterface, FactoryInterface, MapperInterface {
 }
diff --git a/core/lib/Drupal/Core/Entity/EntityWithPluginBagsInterface.php b/core/lib/Drupal/Core/Entity/EntityWithPluginBagsInterface.php
index a111c73b13c7fb9cefffa068bc828905218d322f..96eee073f6451585d217ed9af64623ce11e2f64c 100644
--- a/core/lib/Drupal/Core/Entity/EntityWithPluginBagsInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityWithPluginBagsInterface.php
@@ -11,6 +11,8 @@
  * Provides an interface for an object utilizing a plugin bag.
  *
  * @see \Drupal\Component\Plugin\PluginBag
+ *
+ * @ingroup plugin_api
  */
 interface EntityWithPluginBagsInterface extends EntityInterface {
 
diff --git a/core/lib/Drupal/Core/Executable/ExecutableInterface.php b/core/lib/Drupal/Core/Executable/ExecutableInterface.php
index 30450c0966793b273b7cbedd7d28b288a5aac861..36fbd518d6492e1050602da413cc95f2361009cd 100644
--- a/core/lib/Drupal/Core/Executable/ExecutableInterface.php
+++ b/core/lib/Drupal/Core/Executable/ExecutableInterface.php
@@ -9,6 +9,8 @@
 
 /**
  * An interface for executable plugins.
+ *
+ * @ingroup plugin_api
  */
 interface ExecutableInterface {
 
diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
index 4f426cc776d7e1e6f3ed486a40f319c1be5ad7e5..4059e100e5993d334ca8dd1b559fd092fb10fe85 100644
--- a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
+++ b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
@@ -23,6 +23,8 @@
 
 /**
  * Base class for plugin managers.
+ *
+ * @ingroup plugin_api
  */
 class DefaultPluginManager extends PluginManagerBase implements PluginManagerInterface, CachedDiscoveryInterface {
 
diff --git a/core/lib/Drupal/Core/Plugin/PluginBase.php b/core/lib/Drupal/Core/Plugin/PluginBase.php
index daaf99acc64c5941ea0556be5d95042d5fc01990..1af9b82394ae7cdfc7f704065ccbfc636e895237 100644
--- a/core/lib/Drupal/Core/Plugin/PluginBase.php
+++ b/core/lib/Drupal/Core/Plugin/PluginBase.php
@@ -13,6 +13,8 @@
 
 /**
  * Base class for plugins supporting metadata inspection and translation.
+ *
+ * @ingroup plugin_api
  */
 abstract class PluginBase extends ComponentPluginBase {
   use StringTranslationTrait;
diff --git a/core/lib/Drupal/Core/Plugin/PluginFormInterface.php b/core/lib/Drupal/Core/Plugin/PluginFormInterface.php
index 9ca47e01d692e1e3451c68ea8e1613341e8abf6f..daceeacd260f1fc0398836a7411fc5c3e35b7fa7 100644
--- a/core/lib/Drupal/Core/Plugin/PluginFormInterface.php
+++ b/core/lib/Drupal/Core/Plugin/PluginFormInterface.php
@@ -9,6 +9,8 @@
 
 /**
  * Provides an interface for a plugin that contains a form.
+ *
+ * @ingroup plugin_api
  */
 interface PluginFormInterface {
 
diff --git a/core/modules/search/search.module b/core/modules/search/search.module
index ce71ab5112fb5acb1f951f2182787934bc26e7c0..a59dcc2dff7e90bb2942b8afa2a34ef24e39958f 100644
--- a/core/modules/search/search.module
+++ b/core/modules/search/search.module
@@ -551,12 +551,7 @@ function search_mark_for_reindex($type, $sid) {
  * data. Most of the system is handled by the Search module, so this must be
  * enabled for all of the search features to work.
  *
- * To be discovered, the plugins must implement
- * \Drupal\search\Plugin\SearchInterface and be annotated as
- * \Drupal\search\Annotation\SearchPlugin plugins. Defining a plugin will allow
- * administrators to set up one or more search pages using this plugin.
- *
- * There are three ways to interact with the search system:
+ * There are two ways to interact with the search system:
  * - Specifically for searching nodes, you can implement
  *   hook_node_update_index() and hook_node_search_result(). However, note that
  *   the search system already indexes all visible output of a node; i.e.,
@@ -569,12 +564,16 @@ function search_mark_for_reindex($type, $sid) {
  *   Each of these corresponds to a tab on the /search page, which can be
  *   used to perform searches. You will also need to implement the execute()
  *   method from the interface to perform the search. A base class is provided
- *   in \Drupal\search\Plugin\SearchPluginBase.
+ *   in \Drupal\search\Plugin\SearchPluginBase. For more information about
+ *   plugins, see the @link plugin_api Plugin API topic. @endlink
  *
  * If your module needs to provide a more complicated search form, then you
  * need to implement it yourself. In that case, you may wish to define it as a
  * local task (tab) under the /search page (e.g. /search/mymodule) so that users
  * can easily find it.
+ *
+ * @see plugin_api
+ * @see annotation
  */
 
 /**
diff --git a/core/modules/system/core.api.php b/core/modules/system/core.api.php
index 5dabffe6f02d68bb2cfac01e3f37f166f2d95932..ef0c0a1ce80dc05ed741255ff32f1b42a147530d 100644
--- a/core/modules/system/core.api.php
+++ b/core/modules/system/core.api.php
@@ -41,6 +41,7 @@
  *
  * @section other_essentials Other essential APIs
  *
+ * - @link plugin_api Plugins @endlink
  * - @link i18n Internationalization @endlink
  * - @link cache Caching @endlink
  * - @link utility Utility classes and functions @endlink
@@ -287,7 +288,7 @@
  *
  * @section define Defining an entity type
  * Entity types are defined by modules, using Drupal's Plugin API (see the
- * @link plugins Plugin API topic @endlink for more information about plugins
+ * @link plugin_api Plugin API topic @endlink for more information about plugins
  * in general). Here are the steps to follow to define a new entity type:
  * - Choose a unique machine name, or ID, for your entity type. This normally
  *   starts with (or is the same as) your module's machine name. It should be
@@ -986,7 +987,7 @@
  *   See the @link hooks Hooks topic @endlink for more information.
  * - Plugins: Classes that a module defines, which are discovered and
  *   instantiated at specific times to add functionality. See the
- *   @link plugins Plugin API topic @endlink for more information.
+ *   @link plugin_api Plugin API topic @endlink for more information.
  * - Entities: Special plugins that define entity types for storing new types
  *   of content or configuration in Drupal. See the
  *   @link entity_api Entity API topic @endlink for more information.
@@ -1001,17 +1002,189 @@
  */
 
 /**
- * @defgroup plugins Plugin API
+ * @defgroup plugin_api Plugin API
  * @{
- * Overview of the Plugin API
+ * Using the Plugin API
  *
- * @todo write this
- *
- * Additional documentation paragraphs need to be written, and functions,
- * classes, and interfaces need to be added to this topic.
+ * @section sec_overview Overview and terminology
+
+ * The basic idea of plugins is to allow a particular module or subsystem of
+ * Drupal to provide functionality in an extensible, object-oriented way. The
+ * controlling module or subsystem defines the basic framework (interface) for
+ * the functionality, and other modules can create plugins (implementing the
+ * interface) with particular behaviors. The controlling module instantiates
+ * existing plugins as needed, and calls methods to invoke their functionality.
+ * Examples of functionality in Drupal Core that use plugins include: the block
+ * system (block types are plugins), the entity/field system (entity types,
+ * field types, field formatters, and field widgets are plugins), the image
+ * manipulation system (image effects and image toolkits are plugins), and the
+ * search system (search page types are plugins).
+ *
+ * Plugins are grouped into plugin types, each generally defined by an
+ * interface. Each plugin type is managed by a plugin manager service, which
+ * uses a plugin discovery method to discover provided plugins of that type and
+ * instantiate them using a plugin factory.
+ *
+ * Some plugin types make use of the following concepts or components:
+ * - Plugin derivatives: Allows a single plugin class to present itself as
+ *   multiple plugins. Example: the Menu module provides a block for each
+ *   defined menu via a block plugin derivative.
+ * - Plugin mapping: Allows a plugin class to map a configuration string to an
+ *   instance, and have the plugin automatically instantiated without writing
+ *   additional code.
+ * - Plugin bags: Provide a way to lazily instantiate a set of plugin
+ *   instances from a single plugin definition.
+ *
+ * There are several things a module developer may need to do with plugins:
+ * - Define a completely new plugin type: see @ref sec_define below.
+ * - Create a plugin of an existing plugin type: see @ref sec_create below.
+ * - Perform tasks that involve plugins: see @ref sec_use below.
+ *
+ * See https://drupal.org/developing/api/8/plugins for more detailed
+ * documentation on the plugin system. There are also topics for a few
+ * of the many existing types of plugins:
+ * - @link block_api Block API @endlink
+ * - @link entity_api Entity API @endlink
+ * - @link field Various types of field-related plugins @endlink
+ * - @link views_plugins Views plugins @endlink (has links to topics covering
+ *   various specific types of Views plugins).
+ * - @link search Search page plugins @endlink
+ *
+ * @section sec_define Defining a new plugin type
+ * To define a new plugin type:
+ * - Define an interface for the plugin. This describes the common set of
+ *   behavior, and the methods you will call on each plugin class that is
+ *   instantiated. Usually this interface will extend one or more of the
+ *   following interfaces:
+ *   - \Drupal\Component\Plugin\PluginInspectionInterface
+ *   - \Drupal\Component\Plugin\ConfigurablePluginInterface
+ *   - \Drupal\Component\Plugin\ContextAwarePluginInterface
+ *   - \Drupal\Core\Plugin\PluginFormInterface
+ *   - \Drupal\Core\Executable\ExecutableInterface
+ * - (optional) Create a base class that provides a partial implementation of
+ *   the interface, for the convenience of developers wishing to create plugins
+ *   of your type. The base class usually extends
+ *   \Drupal\Core\Plugin\PluginBase, or one of the base classes that extends
+ *   this class.
+ * - Choose a method for plugin discovery, and define classes as necessary.
+ *   See @ref sub_discovery below.
+ * - Create a plugin manager/factory class and service, which will discover and
+ *   instantiate plugins. See @ref sub_manager below.
+ * - Use the plugin manager to instantiate plugins. Call methods on your plugin
+ *   interface to perform the tasks of your plugin type.
+ * - (optional) If appropriate, define a plugin bag. See @ref sub_bag below
+ *   for more information.
  *
- * See https://drupal.org/developing/api/8/plugins and links therein for
- * references. This should be an overview and link to details.
+ * @subsection sub_discovery Plugin discovery
+ * Plugin discovery is the process your plugin manager uses to discover the
+ * individual plugins of your type that have been defined by your module and
+ * other modules. Plugin discovery methods are classes that implement
+ * \Drupal\Component\Plugin\Discovery\DiscoveryInterface. Most plugin types use
+ * one of the following discovery mechanisms:
+ * - Annotation: Plugin classes are annotated and placed in a defined namespace
+ *   subdirectory. Most Drupal Core plugins use this method of discovery.
+ * - Hook: Plugin modules need to implement a hook to tell the manager about
+ *   their plugins.
+ * - YAML: Plugins are listd in YAML files. Drupal Core uses this method for
+ *   discovering local tasks and local actions. This is mainly useful if all
+ *   plugins use the same class, so it is kind of like a global derivative.
+ * - Static: Plugin classes are registered within the plugin manager class
+ *   itself. Static discovery is only useful if modules cannot define new
+ *   plugins of this type (if the list of available plugins is static).
+ *
+ * It is also possible to define your own custom discovery mechanism or mix
+ * methods together. And there are many more details, such as annotation
+ * decorators, that apply to some of the discovery methods. See
+ * https://drupal.org/developing/api/8/plugins for more details.
+ *
+ * The remainder of this documentation will assume Annotation-based discovery,
+ * since this is the most common method.
+ *
+ * @subsection sub_manager Defining a plugin manager class and service
+ * To define an annotation-based plugin manager:
+ * - Choose a namespace subdirectory for your plugin. For example, search page
+ *   plugins go in directory Plugin/Search under the module namespace.
+ * - Define an annotation class for your plugin type. This class should extend
+ *   \Drupal\Component\Annotation\Plugin, and for most plugin types, it should
+ *   contain member variables corresponding to the annotations plugins will
+ *   need to provide. All plugins have at least $id: a unique string
+ *   identifier.
+ * - Define an alter hook for altering the discovered plugin definitions. You
+ *   should document the hook in a *.api.php file.
+ * - Define a plugin manager class. This class should implement
+ *   \Drupal\Component\Plugin\PluginManagerInterface; most plugin managers do
+ *   this by extending \Drupal\Core\Plugin\DefaultPluginManager. If you do
+ *   extend the default plugin manager, the only method you will probably need
+ *   to define is the class constructor, which will need to call the parent
+ *   constructor to provide information about the annotation class and plugin
+ *   namespace for discovery, set up the alter hook, and possibly set up
+ *   caching. See classes that extend DefaultPluginManager for examples.
+ * - Define a service for your plugin manager. See the
+ *   @link container Services topic for more information. @endlink Your service
+ *   definition should look something like this, referencing your manager
+ *   class and the parent (default) plugin manager service to inherit
+ *   constructor arguments:
+ *   @code
+ *   plugin.manager.mymodule:
+ *     class: Drupal\mymodule\MyPluginManager
+ *     parent: default_plugin_manager
+ *   @endcode
+ * - If your plugin is configurable, you will also need to define the
+ *   configuration schema and possibly a configuration entity type. See the
+ *   @link config_api Configuration API topic @endlink for more information.
+ *
+ * @subsection sub_bag Defining a plugin bag
+ * Some configurable plugin types allow administrators to create zero or more
+ * instances of each plugin, each with its own configuration. For example,
+ * a single block plugin can be configured several times, to display in
+ * different regions of a theme, with different visibility settings, a
+ * different title, or other plugin-specific settings. To make this possible,
+ * a plugin type can make use of what's known as a plugin bag.
+ *
+ * A plugin bag is a class that extends \Drupal\Component\Plugin\PluginBag or
+ * one of its subclasses; there are several examples in Drupal Core. If your
+ * plugin type uses a plugin bag, it will usually also have a configuration
+ * entity, and the entity class should implement
+ * \Drupal\Core\Entity\EntityWithPluginBagsInterface. Again,
+ * there are several examples in Drupal Core; see also the
+ * @link config_api Configuration API topic @endlink for more information about
+ * configuration entities.
+ *
+ * @section sec_create Creating a plugin of an existing type
+ * Assuming the plugin type uses annotation-based discovery, in order to create
+ * a plugin of an existing type, you will be creating a class. This class must:
+ * - Implement the plugin interface, so that it has the required methods
+ *   defined. Usually, you'll want to extend the plugin base class, if one has
+ *   been provided.
+ * - Have the right annotation in its documentation header. See the
+ *   @link annotation Annotation topic @endlink for more information about
+ *   annotation.
+ * - Be in the right plugin namespace, in order to be discovered.
+ * Often, the easiest way to make sure this happens is to find an existing
+ * example of a working plugin class of the desired type, and copy it into your
+ * module as a starting point.
+ *
+ * You can also create a plugin derivative, which allows your plugin class
+ * to present itself to the user interface as multiple plugins. To do this,
+ * in addition to the plugin class, you'll need to create a separate plugin
+ * derivative class implementing
+ * \Drupal\Component\Plugin\Derivative\DerivativeInterface. The classes
+ * \Drupal\system\Plugin\Block\SystemMenuBlock (plugin class) and
+ * \Drupal\system\Plugin\Derivative\SystemMenuBlock (derivative class) are a
+ * good example to look at.
+ *
+ * @sec sec_use Performing tasks involving plugins
+ * Here are the steps to follow to perform a task that involves plugins:
+ * - Locate the machine name of the plugin manager service, and instantiate the
+ *   service. See the @link container Services topic @endlink for more
+ *   information on how to do this.
+ * - On the plugin manager class, use methods like getDefinition(),
+ *   getDefinitions(), or other methods specific to particular plugin managers
+ *   to retrieve information about either specific plugins or the entire list of
+ *   defined plugins.
+ * - Call the createInstance() method on the plugin manager to instantiate
+ *   individual plugin objects.
+ * - Call methods on the plugin objects to perform the desired tasks.
  *
  * @see annotation
  * @}
diff --git a/core/modules/views/views.api.php b/core/modules/views/views.api.php
index ecc9f723ecaa1517747f4ec325626e7f7813321c..7f87fa9c2e8cb346a91e2614d03ef6b63210b043 100644
--- a/core/modules/views/views.api.php
+++ b/core/modules/views/views.api.php
@@ -12,7 +12,8 @@
  *
  * Views plugins are objects that are used to build and render the view.
  * Plugins are registered by extending one of the Views base plugin classes
- * and defining settings in the plugin annotation.
+ * and defining settings in the plugin annotation. For more information about
+ * plugins, see the @link plugin_api Plugin API topic. @endlink
  *
  * Views has the following types of plugins:
  * - Access: Access plugins are responsible for controlling access to the
@@ -83,7 +84,6 @@
  *   \Drupal\views\Plugin\views\style\StylePluginBase.
  *
  * @todo Add an explanation for each type of handler.
- * @todo Document how to use annotations and what goes in them.
  * @todo Add @ingroup to all the base plugins for this group.
  * @todo Add a separate @ingroup for all plugins?
  * @todo Document specific options on the appropriate plugin base classes.
@@ -91,6 +91,8 @@
  *
  * @see \Drupal\views\Plugin\views\PluginBase
  * @see \Drupal\views\Plugin\views\HandlerBase
+ * @see plugin_api
+ * @see annotation
  */
 
 /**