To implement plugins, you need to implement a single hook in your module to tell the system where your plugins live, and then you need to implement one or more .inc files that contain the plugin data.

Telling it where your plugins live

To implement any plugins at all, you must implement a single function for all plugins: hook_ctools_plugin_directory. Every time a module loads plugins, this hook will be called to see which modules implement those plugins and in what directory those plugins will live.
function hook_ctools_plugin_directory($module, $plugin) {
  if ($module == 'panels' && $plugin == 'content_types') {
    return 'plugins/content_types';
  }
}
The directory returned should be relative to your module. Another common usage is to simply return that you implement all plugins owned by a given module (or modules):
function hook_ctools_plugin_directory($module, $plugin) {
  if ($module == 'panels') {
    return 'plugins/' . $plugin;
  }
}
Typically, it is recommended that all plugins be placed into the 'plugins' directory for clarity and maintainability. Inside the directory, any number of subdirectories can be used. For plugins that require extra files, such as templates, css, javascript or image files, this is highly recommended:
mymodule.module
mymodule.info
plugins/
    content_types/
        my_content_type.inc
    layouts/
        my_layout.inc
        my_laout.css
        my_layout.tpl.php
        my_layout_image.png

How a theme can implement plugins

Themes can implement plugins if the plugin owner specified that it's possible in its hook_ctools_api_TYPE() call. If so, it is generally exactly the same as modules, except for one important difference: themes don't get hook_ctools_plugin_directory(). Instead, themes add a line to their info file:
plugins[module][type] = directory

How to structure the .inc file

The actual plugin .inc file must be named carefully; the name of the file will conform to the name of the plugin. This name must be unique, so you should try to include your module name at the beginning to make sure you don't bump into other modules trying to create a plugin with the same name. This file must contain a specially named function:
function YOURMODULE_PLUGINNAME_OWNERMODULE_PLUGINTYPE()
So for example, for module 'example' to implement a 'layout' named 'mine' for the 'panels' module:
  function example_mine_panels_layouts() {

  }
Finally, your plugin should return an array of data, like this:
function YOURMODULE_PLUGINNAME_OWNERMODULE_PLUGINTYPE() {
  return array(
    'key' => 'value',
  );
}
Several values will be filled in for you automatically, but you can override them if necessary. They include 'name', 'path', 'file' and 'module'. Additionally, the plugin can owner can provide other defaults as well.