diff --git bp-core/admin/bp-core-functions.php bp-core/admin/bp-core-functions.php
index e47e7da..ef11105 100644
--- bp-core/admin/bp-core-functions.php
+++ bp-core/admin/bp-core-functions.php
@@ -74,11 +74,16 @@ add_action( bp_core_admin_hook(), 'bp_core_admin_backpat_menu', 999 );
  * @since BuddyPress (1.6)
  */
 function bp_core_modify_admin_menu_highlight() {
-	global $plugin_page, $submenu_file;
+	global $pagenow, $plugin_page, $submenu_file;
 
 	// This tweaks the Settings subnav menu to show only one BuddyPress menu item
 	if ( ! in_array( $plugin_page, array( 'bp-activity', 'bp-general-settings', ) ) )
 		$submenu_file = 'bp-components';
+
+	// Network Admin > Tools
+	if ( in_array( $plugin_page, array( 'bp-tools', 'available-tools' ) ) ) {
+		$submenu_file = $plugin_page;
+	}
 }
 
 /**
@@ -388,7 +393,7 @@ function bp_core_admin_tabs( $active_tab = '' ) {
 		'2' => array(
 			'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-settings' ), 'admin.php' ) ),
 			'name' => __( 'Settings', 'buddypress' )
-		)
+		),
 	);
 
 	// If forums component is active, add additional tab
diff --git bp-core/admin/bp-core-tools.php bp-core/admin/bp-core-tools.php
index e69de29..32ba8fd 100644
--- bp-core/admin/bp-core-tools.php
+++ bp-core/admin/bp-core-tools.php
@@ -0,0 +1,329 @@
+<?php
+
+/**
+ * BuddyPress Tools panel
+ *
+ * @since BuddyPress (2.0.0)
+ */
+
+/**
+ * Render the BuddyPress Tools page.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_core_admin_tools() {
+	?>
+	<div class="wrap">
+		<?php screen_icon( 'buddypress'); ?>
+
+		<h2><?php esc_html_e( 'BuddyPress Tools', 'buddypress' ) ?></h2>
+
+		<p>
+			<?php esc_html_e( 'BuddyPress keeps track of various relationships between users, groups, and activity items. Occasionally these relationships become out of sync, most often after an import, update, or migration.', 'buddypress' ); ?>
+			<?php esc_html_e( 'Use the tools below to manually recalculate these relationships.', 'buddypress' ); ?>
+		</p>
+		<p class="description"><?php esc_html_e( 'Some of these tools create substantial database overhead. Avoid running more than one repair job at a time.', 'buddypress' ); ?></p>
+
+		<form class="settings" method="post" action="">
+			<table class="form-table">
+				<tbody>
+					<tr valign="top">
+						<th scope="row"><?php esc_html_e( 'Data to Repair:', 'buddypress' ) ?></th>
+						<td>
+							<fieldset>
+								<legend class="screen-reader-text"><span><?php esc_html_e( 'Repair', 'buddypress' ) ?></span></legend>
+
+								<?php foreach ( bp_admin_repair_list() as $item ) : ?>
+
+									<label><input type="checkbox" class="checkbox" name="<?php echo esc_attr( $item[0] ) . '" id="' . esc_attr( str_replace( '_', '-', $item[0] ) ); ?>" value="1" /> <?php echo esc_html( $item[1] ); ?></label><br />
+
+								<?php endforeach; ?>
+
+							</fieldset>
+						</td>
+					</tr>
+				</tbody>
+			</table>
+
+			<fieldset class="submit">
+				<input class="button-primary" type="submit" name="bp-tools-submit" value="<?php esc_attr_e( 'Repair Items', 'buddypress' ); ?>" />
+				<?php wp_nonce_field( 'bp-do-counts' ); ?>
+			</fieldset>
+		</form>
+	</div>
+	<?php
+}
+
+/**
+ * Handle the processing and feedback of the admin tools page.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_admin_repair_handler() {
+	if ( ! bp_is_post_request() ) {
+		return;
+	}
+
+	if ( empty( $_POST['bp-tools-submit'] ) ) {
+		return;
+	}
+
+	check_admin_referer( 'bp-do-counts' );
+
+	// Stores messages
+	$messages = array();
+
+	wp_cache_flush();
+
+	foreach ( (array) bp_admin_repair_list() as $item ) {
+		if ( isset( $item[2] ) && isset( $_POST[$item[0]] ) && 1 === absint( $_POST[$item[0]] ) && is_callable( $item[2] ) ) {
+			$messages[] = call_user_func( $item[2] );
+		}
+	}
+
+	if ( count( $messages ) ) {
+		foreach ( $messages as $message ) {
+			bp_admin_tools_feedback( $message[1] );
+		}
+	}
+}
+add_action( bp_core_admin_hook(), 'bp_admin_repair_handler' );
+
+/**
+ * Get the array of the repair list.
+ *
+ * @return array
+ */
+function bp_admin_repair_list() {
+	// Members:
+	// - member count
+	$repair_list = array(
+		20 => array(
+			'bp-total-member-count',
+			__( 'Count total members', 'buddypress' ),
+			'bp_admin_repair_count_members',
+		),
+	);
+
+	// Friends:
+	// - user friend count
+	if ( bp_is_active( 'friends' ) ) {
+		$repair_list[0] = array(
+			'bp-user-friends',
+			__( 'Count friends for each user', 'buddypress' ),
+			'bp_admin_repair_friend_count',
+		);
+	}
+
+	// Groups:
+	// - user group count
+	if ( bp_is_active( 'groups' ) ) {
+		$repair_list[10] = array(
+			'bp-group-count',
+			__( 'Count groups for each user', 'buddypress' ),
+			'bp_admin_repair_group_count',
+		);
+	}
+
+	ksort( $repair_list );
+
+	return (array) apply_filters( 'bp_repair_list', $repair_list );
+}
+
+/**
+ * Recalculate friend counts for each user.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @return array
+ */
+function bp_admin_repair_friend_count() {
+	global $wpdb, $bp;
+
+	if ( ! bp_is_active( 'friends' ) ) {
+		return;
+	}
+
+	$statement = __( 'Counting the number of friends for each user&hellip; %s', 'buddypress' );
+	$result    = __( 'Failed!', 'buddypress' );
+
+	$sql_delete = "DELETE FROM {$wpdb->usermeta} WHERE meta_key IN ( 'total_friend_count' );";
+	if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) {
+		return array( 1, sprintf( $statement, $result ) );
+	}
+
+	// Walk through all users on the site
+	$total_users = $wpdb->get_row( "SELECT count(ID) as c FROM {$wpdb->users}" )->c;
+
+	$updated = array();
+	if ( $total_users > 0 ) {
+		$per_query = 500;
+		$offset = 0;
+		while ( $offset < $total_users ) {
+			// Only bother updating counts for users who actually have friendships
+			$friendships = $wpdb->get_results( $wpdb->prepare( "SELECT initiator_user_id, friend_user_id FROM {$bp->friends->table_name} WHERE is_confirmed = 1 AND ( ( initiator_user_id > %d AND initiator_user_id <= %d ) OR ( friend_user_id > %d AND friend_user_id <= %d ) )", $offset, $offset + $per_query, $offset, $offset + $per_query ) );
+
+			// The previous query will turn up duplicates, so we
+			// filter them here
+			foreach ( $friendships as $friendship ) {
+				if ( ! isset( $updated[ $friendship->initiator_user_id ] ) ) {
+					BP_Friends_Friendship::total_friend_count( $friendship->initiator_user_id );
+					$updated[ $friendship->initiator_user_id ] = 1;
+				}
+
+				if ( ! isset( $updated[ $friendship->friend_user_id ] ) ) {
+					BP_Friends_Friendship::total_friend_count( $friendship->friend_user_id );
+					$updated[ $friendship->friend_user_id ] = 1;
+				}
+			}
+
+			$offset += $per_query;
+		}
+	} else {
+		return array( 2, sprintf( $statement, $result ) );
+	}
+
+	return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
+}
+
+/**
+ * Recalculate group counts for each user.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @return array
+ */
+function bp_admin_repair_group_count() {
+	global $wpdb, $bp;
+
+	if ( ! bp_is_active( 'groups' ) ) {
+		return;
+	}
+
+	$statement = __( 'Counting the number of groups for each user&hellip; %s', 'buddypress' );
+	$result    = __( 'Failed!', 'buddypress' );
+
+	$sql_delete = "DELETE FROM {$wpdb->usermeta} WHERE meta_key IN ( 'total_group_count' );";
+	if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) {
+		return array( 1, sprintf( $statement, $result ) );
+	}
+
+	// Walk through all users on the site
+	$total_users = $wpdb->get_row( "SELECT count(ID) as c FROM {$wpdb->users}" )->c;
+
+	if ( $total_users > 0 ) {
+		$per_query = 500;
+		$offset = 0;
+		while ( $offset < $total_users ) {
+			// But only bother to update counts for users that have groups
+			$users = $wpdb->get_col( $wpdb->prepare( "SELECT user_id FROM {$bp->groups->table_name_members} WHERE is_confirmed = 1 AND is_banned = 0 AND user_id > %d AND user_id <= %d", $offset, $offset + $per_query ) );
+
+			foreach ( $users as $user ) {
+				BP_Groups_Member::refresh_total_group_count_for_user( $user );
+			}
+
+			$offset += $per_query;
+		}
+	} else {
+		return array( 2, sprintf( $statement, $result ) );
+	}
+
+	return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
+}
+
+/**
+ * Recalculate the total number of active site members.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_admin_repair_count_members() {
+	$statement = __( 'Counting the number of active members on the site&hellip; %s', 'buddypress' );
+	delete_transient( 'bp_active_member_count' );
+	bp_core_get_active_member_count();
+	return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
+}
+
+/**
+ * Assemble admin notices relating success/failure of repair processes.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $message Feedback message.
+ * @param unknown $class Unused.
+ */
+function bp_admin_tools_feedback( $message, $class = false ) {
+	if ( is_string( $message ) ) {
+		$message = '<p>' . $message . '</p>';
+		$class = $class ? $class : 'updated';
+	} elseif ( is_wp_error( $message ) ) {
+		$errors = $message->get_error_messages();
+
+		switch ( count( $errors ) ) {
+			case 0:
+				return false;
+				break;
+
+			case 1:
+				$message = '<p>' . $errors[0] . '</p>';
+				break;
+
+			default:
+				$message = '<ul>' . "\n\t" . '<li>' . implode( '</li>' . "\n\t" . '<li>', $errors ) . '</li>' . "\n" . '</ul>';
+				break;
+		}
+
+		$class = $class ? $class : 'error';
+	} else {
+		return false;
+	}
+
+	$message = '<div id="message" class="' . esc_attr( $class ) . '">' . $message . '</div>';
+	$message = str_replace( "'", "\'", $message );
+	$lambda  = create_function( '', "echo '$message';" );
+
+	add_action( 'admin_notices', $lambda );
+
+	return $lambda;
+}
+
+/**
+ * Render the Available Tools page.
+ *
+ * We register this page on Network Admin as a top-level home for our
+ * BuddyPress tools. This displays the default content.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_core_admin_available_tools_page() {
+	?>
+	<div class="wrap">
+		<h2><?php esc_attr_e( 'Tools', 'buddypress' ) ?></h2>
+
+		<?php do_action( 'bp_network_tool_box' );?>
+
+	</div>
+	<?php
+}
+
+/**
+ * Render an introduction of BuddyPress tools on Available Tools page.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_core_admin_available_tools_intro() {
+	$query_arg = array(
+		'page' => 'bp-tools'
+	);
+	
+	$page = bp_core_do_network_admin() ? 'admin.php' : 'tools.php' ; 
+	$url  = add_query_arg( $query_arg, bp_get_admin_url( $page ) );
+	?>
+	<div class="tool-box">
+		<h3 class="title"><?php esc_html_e( 'BuddyPress Tools', 'buddypress' ) ?></h3>
+		<p>
+			<?php esc_html_e( 'BuddyPress keeps track of various relationships between users, groups, and activity items. Occasionally these relationships become out of sync, most often after an import, update, or migration.', 'buddypress' ); ?>
+			<?php printf( _x( 'Use the %s.', 'buddypress tools intro', 'buddypress' ), '<a href="' . esc_url( $url ) . '">' . esc_html__( 'BuddyPress Tools', 'buddypress' ) . '</a>' ); ?>
+		</p>
+	</div>
+	<?php
+}
\ No newline at end of file
diff --git bp-core/admin/css/common.css bp-core/admin/css/common.css
index 17548ec..e476679 100644
--- bp-core/admin/css/common.css
+++ bp-core/admin/css/common.css
@@ -90,6 +90,12 @@ body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups_network.current .wp-menu
 body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups_network.wp-has-current-submenu .wp-menu-image {
 	background-position: -61px -2px;
 }
+
+/* Tools */
+#adminmenu .toplevel_page_network-tools div.wp-menu-image:before {
+    content: "";
+}
+
 th.column-gid {
 	width: 60px;
 }
diff --git bp-core/bp-core-admin.php bp-core/bp-core-admin.php
index 4020355..f6cfc3a 100644
--- bp-core/bp-core-admin.php
+++ bp-core/bp-core-admin.php
@@ -118,6 +118,7 @@ class BP_Admin {
 		require( $this->admin_dir . 'bp-core-functions.php'  );
 		require( $this->admin_dir . 'bp-core-components.php' );
 		require( $this->admin_dir . 'bp-core-slugs.php'      );
+		require( $this->admin_dir . 'bp-core-tools.php'      );
 	}
 
 	/**
@@ -153,6 +154,10 @@ class BP_Admin {
 		// Add a link to BuddyPress About page to the admin bar
 		add_action( 'admin_bar_menu', array( $this, 'admin_bar_about_link' ), 15 );
 
+		// Add a description of new BuddyPress tools in the available tools page
+		add_action( 'tool_box', 'bp_core_admin_available_tools_intro' );
+		add_action( 'bp_network_tool_box', 'bp_core_admin_available_tools_intro' );
+
 		/** Filters ***********************************************************/
 
 		// Add link to settings page
@@ -242,6 +247,42 @@ class BP_Admin {
 			'bp_core_admin_settings'
 		);
 
+		// For consistency with non-Multisite, we add a Tools menu in
+		// the Network Admin as a home for our Tools panel
+		if ( is_multisite() && bp_core_do_network_admin() ) {
+			$tools_parent = 'network-tools';
+
+			$hooks[] = add_menu_page(
+				__( 'Tools', 'buddypress' ),
+				__( 'Tools', 'buddypress' ),
+				'manage_network_options',
+				$tools_parent,
+				'bp_core_tools_top_level_item',
+				'',
+				24 // just above Settings
+			);
+
+			$hooks[] = add_submenu_page(
+				$tools_parent,
+				__( 'Available Tools', 'buddypress' ),
+				__( 'Available Tools', 'buddypress' ),
+				'manage_network_options',
+				'available-tools',
+				'bp_core_admin_available_tools_page'
+			);
+		} else {
+			$tools_parent = 'tools.php';
+		}
+
+		$hooks[] = add_submenu_page(
+			$tools_parent,
+			__( 'BuddyPress Tools', 'buddypress' ),
+			__( 'BuddyPress', 'buddypress' ),
+			'manage_options',
+			'bp-tools',
+			'bp_core_admin_tools'
+		);
+
 		// Fudge the highlighted subnav item when on a BuddyPress admin page
 		foreach( $hooks as $hook ) {
 			add_action( "admin_head-$hook", 'bp_core_modify_admin_menu_highlight' );
@@ -401,6 +442,9 @@ class BP_Admin {
 		remove_submenu_page( $this->settings_page, 'bp-page-settings' );
 		remove_submenu_page( $this->settings_page, 'bp-settings'      );
 
+		// Network Admin Tools
+		remove_submenu_page( 'network-tools', 'network-tools' );
+
 		// About and Credits pages
 		remove_submenu_page( 'index.php', 'bp-about'   );
 		remove_submenu_page( 'index.php', 'bp-credits' );
