diff --git a/features.drush.inc b/features.drush.inc
index 0d7a10d..ae5e88b 100644
--- a/features.drush.inc
+++ b/features.drush.inc
@@ -117,10 +117,136 @@ function features_drush_command() {
     'drupal dependencies' => array('features', 'diff'),
     'aliases' => array('fd'),
   );
+  $items['features-list-packages'] = array(
+    'description' => 'Lists all feature packages.',
+    'arguments' => array(),
+    'options' => array(
+      'reg' => 'List regular names instead.',
+    ),
+    'drupal_dependencies' => array('features'),
+    'aliases' => array('flp')
+  );
+  $items['features-revert-package'] = array(
+    'description' => "Reverts all features in a specific package(s).",
+    'arguments' => array(
+      'packages' => 'Space-separated list of packages to revert.'
+    ),
+    'drupal dependencies' => array('features'),
+    'aliases' => array('frp')
+  );
+  $items['features-update-package'] = array(
+    'description' => "Updates all features in a specific package(s).",
+    'arguments' => array(
+      'packages' => 'Space-separated list of packages to update.'
+    ),
+    'drupal dependencies' => array('features'),
+    'aliases' => array('fup')
+  );
 
   return $items;
 }
 
+function drush_features_list_packages() {
+  module_load_include('inc', 'features', 'features.export');
+  $features = array_filter(features_get_features(), '_filter_hidden');
+  $packages = array();
+  foreach ($features as $name => $module) {
+    $package_title = !empty($module->info['package']) ? $module->info['package'] : t('Other');
+    $package = strtolower(preg_replace('/[^a-zA-Z0-9-]+/', '-', $package_title));
+    $packages[$package] = $package_title;
+  }
+  ksort($packages);
+  foreach ($packages as $package => $name) {
+    print (drush_get_option(array('reg','r'),NULL) ? $name : $package) . "\n";
+  }
+}
+
+function drush_features_revert_package() {
+  module_load_include('inc', 'features', 'features.export');
+  print "\n";
+  if ($args = func_get_args()) {
+    $features = array_filter(features_get_features(), '_filter_hidden');
+    ksort($features);
+    $packages = $args;
+    $features_to_revert = array();
+    foreach ($features as $name => $module) {
+      $package_title = !empty($module->info['package']) ? $module->info['package'] : t('Other');
+      $package = strtolower(preg_replace('/[^a-zA-Z0-9-]+/', '-', $package_title));
+      if ($module->status && in_array($package, $packages)) {
+        switch (features_get_storage($module->name)) {
+          case FEATURES_OVERRIDDEN:
+          case FEATURES_NEEDS_REVIEW:
+          case FEATURES_REBUILDABLE:
+            $features_to_revert[] = $module->name;
+            break;
+        }
+      }
+    }
+
+    if ($features_to_revert) {
+      drush_print(dt('The following modules will be reverted: !modules', array('!modules' => implode(', ', $features_to_revert))));
+      if (drush_confirm(dt('Do you really want to continue?'))) {
+        foreach ($features_to_revert as $module) {
+          drush_invoke_process(drush_sitealias_get_record('@self'), 'features-revert', array($module), array('force' => $force, '#integrate' => TRUE));
+        }
+      }
+      else {
+        return drush_user_abort('Aborting.');
+      }
+    }
+    else {
+      drush_log(dt('Current state already matches defaults, aborting.'), 'ok');
+    }
+
+  }
+  else {
+    return drush_set_error('', 'No feature package names were given.');
+  }
+}
+
+function drush_features_update_package() {
+  module_load_include('inc', 'features', 'features.export');
+  print "\n";
+  if ($args = func_get_args()) {
+    $features = array_filter(features_get_features(), '_filter_hidden');
+    ksort($features);
+    $packages = $args;
+    $features_to_update = array();
+    foreach ($features as $name => $module) {
+      $package_title = !empty($module->info['package']) ? $module->info['package'] : t('Other');
+      $package = strtolower(preg_replace('/[^a-zA-Z0-9-]+/', '-', $package_title));
+      if ($module->status && in_array($package, $packages)) {
+        switch (features_get_storage($module->name)) {
+          case FEATURES_OVERRIDDEN:
+          case FEATURES_NEEDS_REVIEW:
+          case FEATURES_REBUILDABLE:
+            $features_to_update[] = $module->name;
+            break;
+        }
+      }
+    }
+
+    if ($features_to_update) {
+      drush_print(dt('The following modules will be updated: !modules', array('!modules' => implode(', ', $features_to_update))));
+      if (drush_confirm(dt('Do you really want to continue?'))) {
+        foreach ($features_to_update as $module) {
+          drush_invoke_process(drush_sitealias_get_record('@self'), 'features-update', array($module));
+        }
+      }
+      else {
+        return drush_user_abort('Aborting.');
+      }
+    }
+    else {
+      drush_log(dt('Current state already matches defaults, aborting.'), 'ok');
+    }
+
+  }
+  else {
+    return drush_set_error('', 'No feature package names were given.');
+  }
+}
+
 /**
  * Implements hook_drush_help().
  */
@@ -813,3 +939,7 @@ function _features_drush_set_error($feature, $error = '') {
 
   return drush_set_error($error, dt($message, $args));
 }
+
+function _filter_hidden($module) {
+  return empty($module->info['hidden']);
+}
