diff --git a/flag.inc b/flag.inc
index b8570d9..2e43495 100644
--- a/flag.inc
+++ b/flag.inc
@@ -193,6 +193,7 @@ class flag_flag {
         'flag' => array(DRUPAL_AUTHENTICATED_RID),
         'unflag' => array(DRUPAL_AUTHENTICATED_RID),
       ),
+      'weight' => 0,
     );
 
     // Merge in options from the current link type.
@@ -1779,7 +1780,6 @@ class FlagGlobalCookieStorage extends FlagCookieStorage {
     }
   }
 }
-
 /**
  * Storage handler for non-global flags.
  */
diff --git a/flag.module b/flag.module
index b383890..da108da 100644
--- a/flag.module
+++ b/flag.module
@@ -985,10 +985,18 @@ function flag_theme() {
       'variables' => array('types' => array('all'), 'prefix' => '[', 'suffix' => ']'),
       'file' => 'includes/flag.token.inc',
     ),
-    'flag_admin_page' => array(
+    'flag_admin_listing' => array(
+      'variables' => array('form' => NULL),
+      'file' => 'includes/flag.admin.inc',
+    ),
+    'flag_admin_listing_disabled' => array(
       'arguments' => array('flags' => NULL, 'default_flags' => NULL),
       'file' => 'includes/flag.admin.inc',
     ),
+    'flag_admin_page' => array(
+      'arguments' => array('flags' => NULL, 'default_flags' => NULL, 'flag_admin_listing' => NULL),
+      'file' => 'includes/flag.admin.inc',
+    ),
     'flag_form_roles' => array(
       'arguments' => array('element' => NULL),
       'file' => 'includes/flag.admin.inc',
@@ -1275,6 +1283,9 @@ function flag_get_flags($content_type = NULL, $content_subtype = NULL, $account
       }
     }
 
+    // Sort the list of flags by weight.
+    uasort($flags, '_flag_compare_weight');
+
     // Allow modules implementing hook_flag_alter(&$flag) to modify each flag.
     foreach ($flags as $flag) {
       drupal_alter('flag', $flag);
@@ -1308,6 +1319,16 @@ function flag_get_flags($content_type = NULL, $content_subtype = NULL, $account
 }
 
 /**
+ * Comparison function for uasort().
+ */
+function _flag_compare_weight($flag1, $flag2) {
+  if ($flag1->weight == $flag2->weight) {
+    return 0;
+  }
+  return $flag1->weight < $flag2->weight ? -1 : 1;
+}
+
+/**
  * Utility function: Checks whether a flag applies to a certain type, and
  * possibly subtype, of content.
  *
diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc
index 110b0cb..80843af 100644
--- a/includes/flag.admin.inc
+++ b/includes/flag.admin.inc
@@ -11,16 +11,54 @@
 function flag_admin_page() {
   $flags = flag_get_flags();
   $default_flags = flag_get_default_flags(TRUE);
-  return theme('flag_admin_page', $flags, $default_flags);
+  $flag_admin_listing = drupal_get_form('flag_admin_listing', $flags);
+  return theme('flag_admin_page', $flags, $default_flags, $flag_admin_listing);
 }
 
 /**
- * Theme the output for the main flag administration page.
+ * A form for ordering the weights of all the active flags in the system.
+**/
+function flag_admin_listing(&$form_state, $flags) {
+  $form['#flags'] = $flags;
+  $form['#tree'] = TRUE;
+
+  foreach ($flags as $flag) {
+    $form['flags'][$flag->name]['weight'] = array(
+      '#type' => 'weight',
+      '#delta' => count($flags) + 5,
+      '#default_value' => $flag->weight,
+      '#attributes' => array('class' => 'flag-weight'),
+    );
+  }
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save flag order'),
+  );
+
+  return $form;
+}
+
+/**
+ * Submit handler for the flag_admin_listing form. Save flag weight ordering.
+ */
+function flag_admin_listing_submit($form, &$form_state) {
+  foreach ($form['#flags'] as $flag) {
+    if ($flag->weight != $form_state['values']['flags'][$flag->name]['weight']) {
+      $flag->weight = $form_state['values']['flags'][$flag->name]['weight'];
+      $flag->save();
+    }
+  }
+}
+
+/**
+ * Theme the output of the normal, database flags into a table.
  */
-function theme_flag_admin_page($flags, $default_flags) {
+function theme_flag_admin_listing($form) {
+  $flags = $form['#flags'];
+
   $output = '';
 
-  // Build out the list of normal, database flags.
   foreach ($flags as $flag) {
     $ops = array(
       'flags_edit' =>  array('title' => t('edit'), 'href' => $flag->admin_path('edit')),
@@ -29,23 +67,41 @@ function theme_flag_admin_page($flags, $default_flags) {
     );
 
     $roles = array_flip(array_intersect(array_flip(user_roles()), $flag->roles['flag']));
-    $rows[] = array(
+    $row = array(
       $flag->name,
+      drupal_render($form['flags'][$flag->name]['weight']),
       $flag->content_type,
       empty($flag->roles['flag']) ? '<em>' . t('No roles') . '</em>' : implode(', ', $roles),
       $flag->types ? implode(', ', $flag->types) : '-',
       $flag->global ? t('Yes') : t('No'),
       theme('links', $ops),
     );
+    $rows[] = array(
+      'data' => $row,
+      'class' => 'draggable',
+    );
   }
   if (!$flags) {
     $rows[] = array(
-      array('data' => t('No flags are currently defined.'), 'colspan' => 6),
+      array('data' => t('No flags are currently defined.'), 'colspan' => 7),
     );
   }
+  else {
+    drupal_add_tabledrag('flag-admin-listing-table', 'order', 'sibling', 'flag-weight');
+  }
 
-  $header = array(t('Flag'), t('Flag type'), t('Roles'), t('Node types'), t('Global?'), t('Operations'));
-  $output .= theme('table', $header, $rows);
+  $header = array(t('Flag'),t('Weight'), t('Flag type'), t('Roles'), t('Node types'), t('Global?'), t('Operations'));
+  $output .= theme('table', $header, $rows, array('id' => 'flag-admin-listing-table'));
+  $output .= drupal_render($form);
+
+  return $output;
+}
+
+/**
+ * Theme the list of disabled flags into a table.
+ */
+function theme_flag_admin_listing_disabled($flags, $default_flags) {
+  $output = '';
 
   // Build a list of disabled, module-based flags.
   $rows = array();
@@ -79,6 +135,18 @@ function theme_flag_admin_page($flags, $default_flags) {
     $output .= theme('table', $header, $rows);
   }
 
+  return $output;
+}
+
+/**
+ * Theme the output for the main flag administration page.
+ */
+function theme_flag_admin_page($flags, $default_flags, $flag_admin_listing) {
+  $output = '';
+
+  $output .= $flag_admin_listing;
+  $output .= theme('flag_admin_listing_disabled', $flags, $default_flags);
+
   if (!module_exists('views')) {
     $output .= '<p>' . t('The <a href="@views-url">Views</a> module is not installed, or not enabled. It is recommended that you install the Views module to be able to easily produce lists of flagged content.', array('@views-url' => url('http://drupal.org/project/views'))) . '</p>';
   }
@@ -156,7 +224,7 @@ function flag_add_form(&$form_state) {
 
   $form['submit'] = array(
     '#type' => 'submit',
-    '#value' => t('Submit'),
+    '#value' => t('Add flag'),
   );
 
   return $form;
@@ -415,7 +483,7 @@ function flag_form(&$form_state, $flag) {
 
   $form['submit'] = array(
     '#type' => 'submit',
-    '#value' => t('Submit'),
+    '#value' => t('Save flag'),
     // We put this button on the form before calling $flag->options_form()
     // to give the flag handler a chance to remove it (e.g. flag_broken).
     '#weight' => 999,
