diff --git src/bp-core/admin/bp-core-admin-functions.php src/bp-core/admin/bp-core-admin-functions.php
index 7749dd449..1b2642448 100644
--- src/bp-core/admin/bp-core-admin-functions.php
+++ src/bp-core/admin/bp-core-admin-functions.php
@@ -85,8 +85,8 @@ function bp_core_modify_admin_menu_highlight() {
 		$submenu_file = $plugin_page;
 	}
 
-	// Keep the BuddyPress tools menu highlighted.
-	if ( 'bp-optouts' === $plugin_page ) {
+	// Keep the BuddyPress tools menu highlighted when using a tools tab.
+	if ( 'bp-optouts' === $plugin_page || 'bp-members-invitations' === $plugin_page ) {
 		$submenu_file = 'bp-tools';
 	}
 }
@@ -284,7 +284,7 @@ function bp_core_activation_notice() {
 
 	// Activate and Register are special cases. They are not components but they need WP pages.
 	// If user registration is disabled, we can skip this step.
-	if ( bp_get_signup_allowed() ) {
+	if ( bp_get_signup_allowed() || bp_get_members_invitations_allowed() ) {
 		$wp_page_components[] = array(
 			'id'   => 'activate',
 			'name' => __( 'Activate', 'buddypress' ),
@@ -479,6 +479,10 @@ function bp_core_get_admin_tabs( $active_tab = '', $context = 'settings' ) {
 				'name' => __( 'Repair', 'buddypress' ),
 			),
 			'1' => array(
+				'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-members-invitations' ), $tools_page ) ),
+				'name' => __( 'Manage Invitations', 'buddypress' ),
+			),
+			'2' => array(
 				'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-optouts' ), $tools_page ) ),
 				'name' => __( 'Manage Opt-outs', 'buddypress' ),
 			),
diff --git src/bp-core/admin/bp-core-admin-optouts.php src/bp-core/admin/bp-core-admin-optouts.php
index d47cf79de..95d789a08 100644
--- src/bp-core/admin/bp-core-admin-optouts.php
+++ src/bp-core/admin/bp-core-admin-optouts.php
@@ -174,26 +174,30 @@ function bp_core_get_optouts_notice() {
 		);
 
 		if ( ! empty( $_REQUEST['deleted'] ) ) {
+			$deleted            = absint( $_REQUEST['deleted'] );
 			$notice['message'] .= sprintf(
-				/* translators: %s: number of deleted optouts */
-				_nx( '%s opt-out successfully deleted!', '%s opt-outs successfully deleted!',
-				 absint( $_REQUEST['deleted'] ),
-				 'nonmembers opt-out deleted',
-				 'buddypress'
+				_nx(
+					/* translators: %s: number of deleted optouts */
+					'%s opt-out successfully deleted!', '%s opt-outs successfully deleted!',
+					$deleted,
+					'nonmembers opt-out deleted',
+					'buddypress'
 				),
 				number_format_i18n( absint( $_REQUEST['deleted'] ) )
 			);
 		}
 
 		if ( ! empty( $_REQUEST['notdeleted'] ) ) {
+			$notdeleted         = absint( $_REQUEST['notdeleted'] );
 			$notice['message'] .= sprintf(
-				/* translators: %s: number of optouts that failed to be deleted */
-				_nx( '%s opt-out was not deleted.', '%s opt-outs were not deleted.',
-				 absint( $_REQUEST['notdeleted'] ),
-				 'nonmembers opt-out not deleted',
-				 'buddypress'
+				_nx(
+					/* translators: %s: number of optouts that failed to be deleted */
+					'%s opt-out was not deleted.', '%s opt-outs were not deleted.',
+					$notdeleted,
+					'nonmembers opt-out not deleted',
+					'buddypress'
 				),
-				number_format_i18n( absint( $_REQUEST['notdeleted'] ) )
+				number_format_i18n( $notdeleted )
 			);
 
 			if ( empty( $_REQUEST['deleted'] ) ) {
diff --git src/bp-core/admin/bp-core-admin-settings.php src/bp-core/admin/bp-core-admin-settings.php
index c09f809ca..b37b914ff 100644
--- src/bp-core/admin/bp-core-admin-settings.php
+++ src/bp-core/admin/bp-core-admin-settings.php
@@ -182,6 +182,27 @@ function bp_admin_setting_callback_cover_image_uploads() {
 <?php
 }
 
+/**
+ * Allow members to invite non-members to the network.
+ *
+ * @since 8.0.0
+ */
+function bp_admin_setting_callback_members_invitations() {
+?>
+	<input id="bp-enable-members-invitations" name="bp-enable-members-invitations" type="checkbox" value="1" <?php checked( bp_get_members_invitations_allowed() ); ?> />
+	<label for="bp-enable-members-invitations"><?php _e( 'Allow registered members to invite people to join this network', 'buddypress' ); ?></label>
+	<?php if ( ! bp_get_signup_allowed() ) : ?>
+		<p class="description"><?php _e( 'Public registration is currently disabled. However, invitees will still be able to register if network invitations are enabled.', 'buddypress' ); ?></p>
+	<?php endif; ?>
+	<?php
+	/**
+	 * Fires after the output of the invitations settings section.
+	 *
+	 * @since 8.0.0
+	 */
+	do_action( 'bp_admin_settings_after_members_invitations' );
+}
+
 /** XProfile ******************************************************************/
 
 /**
diff --git src/bp-core/admin/bp-core-admin-slugs.php src/bp-core/admin/bp-core-admin-slugs.php
index 8fb9b9a40..52ef6e36c 100644
--- src/bp-core/admin/bp-core-admin-slugs.php
+++ src/bp-core/admin/bp-core-admin-slugs.php
@@ -187,7 +187,7 @@ function bp_core_admin_slugs_options() {
 
 		<h3><?php _e( 'Registration', 'buddypress' ); ?></h3>
 
-		<?php if ( bp_get_signup_allowed() ) : ?>
+		<?php if ( bp_get_signup_allowed() || bp_get_members_invitations_allowed() ) : ?>
 			<p><?php _e( 'Associate WordPress Pages with the following BuddyPress Registration pages.', 'buddypress' ); ?></p>
 		<?php else : ?>
 			<?php if ( is_multisite() ) : ?>
@@ -210,7 +210,7 @@ function bp_core_admin_slugs_options() {
 		<table class="form-table">
 			<tbody>
 
-				<?php if ( bp_get_signup_allowed() ) : foreach ( $static_pages as $name => $label ) : ?>
+				<?php if ( bp_get_signup_allowed() || bp_get_members_invitations_allowed() ) : foreach ( $static_pages as $name => $label ) : ?>
 
 					<tr valign="top">
 						<th scope="row">
diff --git src/bp-core/admin/bp-core-admin-tools.php src/bp-core/admin/bp-core-admin-tools.php
index f93549295..bd2a2d3f8 100644
--- src/bp-core/admin/bp-core-admin-tools.php
+++ src/bp-core/admin/bp-core-admin-tools.php
@@ -557,13 +557,27 @@ function bp_core_admin_available_tools_intro() {
 				);
 				?>
 			</dd>
+
+			<dt><?php esc_html_e( 'Manage Invitations', 'buddypress' ) ?></dt>
+			<dd>
+				<?php esc_html_e( 'When enabled, BuddyPress allows your users to invite nonmembers to join your site.', 'buddypress' ); ?>
+				<?php
+				$url = add_query_arg( 'page', 'bp-members-invitations', bp_get_admin_url( $page ) );
+				printf(
+					/* translators: %s: the link to the BuddyPress Invitations management tool screen */
+					esc_html_x( 'Visit %s to manage your site&rsquo;s invitations.', 'buddypress invitations tool intro', 'buddypress' ),
+					'<a href="' . esc_url( $url ) . '">' . esc_html__( 'Invitations', 'buddypress' ) . '</a>'
+				);
+				?>
+			</dd>
+
 			<dt><?php esc_html_e( 'Manage Opt-outs', 'buddypress' ) ?></dt>
 			<dd>
 				<?php esc_html_e( 'BuddyPress stores opt-out requests from people who are not members of this site, but have been contacted via communication from this site, and wish to opt-out from future communication.', 'buddypress' ); ?>
 				<?php
 				$url = add_query_arg( 'page', 'bp-optouts', bp_get_admin_url( $page ) );
 				printf(
-					/* translators: %s: the link to the BuddyPress Nonmember Opt-outs */
+					/* translators: %s: the link to the BuddyPress Nonmember Opt-outs management tool screen */
 					esc_html_x( 'Visit %s to manage your site&rsquo;s opt-out requests.', 'buddypress opt-outs intro', 'buddypress' ),
 					'<a href="' . esc_url( $url ) . '">' . esc_html__( 'Nonmember Opt-outs', 'buddypress' ) . '</a>'
 				);
diff --git src/bp-core/admin/css/common-rtl.css src/bp-core/admin/css/common-rtl.css
index d460dc8d2..1bbd8508a 100644
--- src/bp-core/admin/css/common-rtl.css
+++ src/bp-core/admin/css/common-rtl.css
@@ -317,6 +317,11 @@ body.tools-php .bp-tools dd {
 	margin: 0;
 }
 
+body.tools_page_bp-members-invitations .nav-tab-wrapper,
+body.tools_page_bp-optouts .nav-tab-wrapper {
+	margin-bottom: 1em;
+}
+
 /*
  * 2.4 Tooltips
  */
diff --git src/bp-core/admin/css/common.css src/bp-core/admin/css/common.css
index 0272626bb..d2730f9a9 100644
--- src/bp-core/admin/css/common.css
+++ src/bp-core/admin/css/common.css
@@ -317,6 +317,11 @@ body.tools-php .bp-tools dd {
 	margin: 0;
 }
 
+body.tools_page_bp-members-invitations .nav-tab-wrapper,
+body.tools_page_bp-optouts .nav-tab-wrapper {
+	margin-bottom: 1em;
+}
+
 /*
  * 2.4 Tooltips
  */
diff --git src/bp-core/bp-core-filters.php src/bp-core/bp-core-filters.php
index 735c7090a..1b285555c 100644
--- src/bp-core/bp-core-filters.php
+++ src/bp-core/bp-core-filters.php
@@ -1067,12 +1067,19 @@ function bp_email_set_default_headers( $headers, $property, $transform, $email )
 
 	// Add 'List-Unsubscribe' header if applicable.
 	if ( ! empty( $tokens['unsubscribe'] ) && $tokens['unsubscribe'] !== wp_login_url() ) {
-		$user = get_user_by( 'email', $tokens['recipient.email'] );
+		$user    = get_user_by( 'email', $tokens['recipient.email'] );
+		$user_id = isset( $user->ID ) ? $user->ID : 0;
 
-		$link = bp_email_get_unsubscribe_link( array(
-			'user_id'           => $user->ID,
+		$args = array(
+			'user_id'           => $user_id,
 			'notification_type' => $email->get( 'type' ),
-		) );
+		);
+		// If this email is not to a current member, include the nonmember's email address.
+		if ( ! $user_id ) {
+			$args['email_address'] = $tokens['recipient.email'];
+		}
+
+		$link = bp_email_get_unsubscribe_link( $args );
 
 		if ( ! empty( $link ) ) {
 			$headers['List-Unsubscribe'] = sprintf( '<%s>', esc_url_raw( $link ) );
diff --git src/bp-core/bp-core-functions.php src/bp-core/bp-core-functions.php
index 1535afed4..98b46f5ce 100644
--- src/bp-core/bp-core-functions.php
+++ src/bp-core/bp-core-functions.php
@@ -702,7 +702,7 @@ function bp_core_add_page_mappings( $components, $existing = 'keep' ) {
 
 	// Register and Activate are not components, but need pages when
 	// registration is enabled.
-	if ( bp_get_signup_allowed() ) {
+	if ( bp_get_signup_allowed() || bp_get_members_invitations_allowed()  ) {
 		foreach ( array( 'register', 'activate' ) as $slug ) {
 			if ( ! isset( $pages[ $slug ] ) ) {
 				$pages_to_create[ $slug ] = $page_titles[ $slug ];
@@ -3472,6 +3472,9 @@ function bp_send_email( $email_type, $to, $args = array() ) {
 	// From, subject, content are set automatically.
 	if ( 'settings-verify-email-change' === $email_type && isset( $args['tokens']['displayname'] ) ) {
 		$email->set_to( $to, $args['tokens']['displayname'] );
+	// Emails sent to nonmembers will have no recipient.name populated.
+	} else if ( 'bp-members-invitation' === $email_type ) {
+		$email->set_to( $to, $to );
 	} else {
 		$email->set_to( $to );
 	}
@@ -3815,9 +3818,9 @@ function bp_email_get_schema() {
 			/* translators: do not remove {} brackets or translate its contents. */
 			'post_title'   => __( '[{{{site.name}}}] You have an invitation to the group: "{{group.name}}"', 'buddypress' ),
 			/* translators: do not remove {} brackets or translate its contents. */
-			'post_content' => __( "<a href=\"{{{inviter.url}}}\">{{inviter.name}}</a> has invited you to join the group: &quot;{{group.name}}&quot;.\n{{invite.message}}\n<a href=\"{{{invites.url}}}\">Go here to accept your invitation</a> or <a href=\"{{{group.url}}}\">visit the group</a> to learn more.", 'buddypress' ),
+			'post_content' => __( "<a href=\"{{{inviter.url}}}\">{{inviter.name}}</a> has invited you to join the group: &quot;{{group.name}}&quot;.\n\n{{invite.message}}\n\n<a href=\"{{{invites.url}}}\">Go here to accept your invitation</a> or <a href=\"{{{group.url}}}\">visit the group</a> to learn more.", 'buddypress' ),
 			/* translators: do not remove {} brackets or translate its contents. */
-			'post_excerpt' => __( "{{inviter.name}} has invited you to join the group: \"{{group.name}}\".\n\nTo accept your invitation, visit: {{{invites.url}}}\n\nTo learn more about the group, visit: {{{group.url}}}.\nTo view {{inviter.name}}'s profile, visit: {{{inviter.url}}}", 'buddypress' ),
+			'post_excerpt' => __( "{{inviter.name}} has invited you to join the group: \"{{group.name}}\".\n\n{{invite.message}}\n\nTo accept your invitation, visit: {{{invites.url}}}\n\nTo learn more about the group, visit: {{{group.url}}}.\nTo view {{inviter.name}}'s profile, visit: {{{inviter.url}}}", 'buddypress' ),
 		),
 		'groups-member-promoted' => array(
 			/* translators: do not remove {} brackets or translate its contents. */
@@ -3867,6 +3870,14 @@ function bp_email_get_schema() {
 			/* translators: do not remove {} brackets or translate its contents. */
 			'post_excerpt' => __( "Your membership request for the group \"{{group.name}}\" has been rejected.\n\nTo request membership again, visit: {{{group.url}}}", 'buddypress' ),
 		),
+		'bp-members-invitation' => array(
+			/* translators: do not remove {} brackets or translate its contents. */
+			'post_title'   => __( '{{inviter.name}} has invited you to join {{site.name}}', 'buddypress' ),
+			/* translators: do not remove {} brackets or translate its contents. */
+			'post_content' => __( "<a href=\"{{{inviter.url}}}\">{{inviter.name}}</a> has invited you to join the site: &quot;{{site.name}}&quot;.\n\n{{usermessage}}\n\n<a href=\"{{{invite.accept_url}}}\">Accept your invitation</a> or <a href=\"{{{site.url}}}\">visit the site</a> to learn more.", 'buddypress' ),
+			/* translators: do not remove {} brackets or translate its contents. */
+			'post_excerpt' => __( "{{inviter.name}} has invited you to join the site \"{{site.name}}\".\n\n{{usermessage}}\n\nTo accept your invitation, visit: {{{invite.accept_url}}}\n\nTo learn more about the site, visit: {{{site.url}}}.\nTo view {{inviter.name}}'s profile, visit: {{{inviter.url}}}", 'buddypress' ),
+		),
 	) );
 }
 
@@ -4012,6 +4023,14 @@ function bp_email_get_type_schema( $field = 'description' ) {
 		'description'	=> __( 'Recipient has successfully activated an account.', 'buddypress' ),
 	);
 
+	$members_invitation = array(
+		'description'	=> __( 'A site member has sent a site invitation to the recipient.', 'buddypress' ),
+		'unsubscribe'	=> array(
+			'meta_key'	=> 'notification_bp_members_invite',
+			'message'	=> __( 'You will no longer receive emails when you are invited to join a site.', 'buddypress' ),
+		),
+	);
+
 	$types = array(
 		'activity-comment'                   => $activity_comment,
 		'activity-comment-author'            => $activity_comment_author,
@@ -4030,6 +4049,7 @@ function bp_email_get_type_schema( $field = 'description' ) {
 		'groups-membership-request-accepted' => $groups_membership_request_accepted,
 		'groups-membership-request-rejected' => $groups_membership_request_rejected,
 		'core-user-activation'               => $core_user_activation,
+		'bp-members-invitation'              => $members_invitation,
 	);
 
 	if ( $field !== 'all' ) {
@@ -4049,10 +4069,18 @@ function bp_email_unsubscribe_handler() {
 	$raw_email_type = ! empty( $_GET['nt'] ) ? $_GET['nt'] : '';
 	$raw_hash       = ! empty( $_GET['nh'] ) ? $_GET['nh'] : '';
 	$raw_user_id    = ! empty( $_GET['uid'] ) ? absint( $_GET['uid'] ) : 0;
-	$new_hash       = hash_hmac( 'sha1', "{$raw_email_type}:{$raw_user_id}", bp_email_get_salt() );
+	$raw_user_email = ! empty( $_GET['uem'] ) ? $_GET['uem'] : '';
+	$raw_member_id  = ! empty( $_GET['mid'] ) ? absint( $_GET['mid'] ) : 0;
+
+	$new_hash = '';
+	if ( ! empty( $raw_user_id ) ) {
+		$new_hash = hash_hmac( 'sha1', "{$raw_email_type}:{$raw_user_id}", bp_email_get_salt() );
+	} else if ( ! empty( $raw_user_email ) ) {
+		$new_hash = hash_hmac( 'sha1', "{$raw_email_type}:{$raw_user_email}", bp_email_get_salt() );
+	}
 
 	// Check required values.
-	if ( ! $raw_user_id || ! $raw_email_type || ! $raw_hash || ! array_key_exists( $raw_email_type, $emails ) ) {
+	if ( ( ! $raw_user_id && ! $raw_user_email ) || ! $raw_email_type || ! $raw_hash || ! array_key_exists( $raw_email_type, $emails ) ) {
 		$redirect_to = wp_login_url();
 		$result_msg  = __( 'Something has gone wrong.', 'buddypress' );
 		$unsub_msg   = __( 'Please log in and go to your settings to unsubscribe from notification emails.', 'buddypress' );
@@ -4078,6 +4106,22 @@ function bp_email_unsubscribe_handler() {
 			$redirect_to = bp_core_get_user_domain( get_current_user_id() );
 		}
 
+	// This is an unsubscribe request from a nonmember.
+	} else if ( $raw_user_email ) {
+		// Unsubscribe.
+		error_log( 'caught unsubscribe request {$raw_user_email}' );
+		$optout_args = array(
+			'email_address' => $raw_user_email,
+			'user_id'       => $raw_member_id,
+			'email_type'    => $raw_email_type,
+			'date_modified' => bp_core_current_time(),
+		);
+		$result      = bp_add_optout( $optout_args );
+		$redirect_to = home_url();
+		$result_msg  = $emails[ $raw_email_type ]['unsubscribe']['message'];
+		$unsub_msg   = __( 'You have been unsubscribed.', 'buddypress' );
+
+	// This is an unsubscribe request from a current member.
 	} else {
 		if ( bp_is_active( 'settings' ) ) {
 			$redirect_to = sprintf(
@@ -4105,7 +4149,13 @@ function bp_email_unsubscribe_handler() {
 	);
 
 	bp_core_add_message( $message );
-	bp_core_redirect( bp_core_get_user_domain( $raw_user_id ) );
+
+	$page_redirect = '';
+	if ( $raw_user_id  ) {
+		$page_redirect = bp_core_get_user_domain( $raw_user_id );
+	}
+
+	bp_core_redirect( $page_redirect );
 
 	exit;
 }
@@ -4122,6 +4172,7 @@ function bp_email_unsubscribe_handler() {
  *    @type string $notification_type Which notification type is being sent.
  *    @type string $user_id           The ID of the user to whom the notification is sent.
  *    @type string $redirect_to       Optional. The url to which the user will be redirected. Default is the activity directory.
+ *    @type string $email             Optional. The email address of the user to whom the notification is sent.
  * }
  * @return string The unsubscribe link.
  */
@@ -4141,15 +4192,34 @@ function bp_email_get_unsubscribe_link( $args ) {
 		return '';
 	}
 
-	$link = add_query_arg(
-		array(
-			'action' => 'unsubscribe',
-			'nh'     => hash_hmac( 'sha1', "{$email_type}:{$user_id}", bp_email_get_salt() ),
-			'nt'     => $args['notification_type'],
-			'uid'    => $user_id,
-		),
-		$redirect_to
-	);
+	$link = '';
+	// Case where the recipient is a member of the site.
+	if ( ! empty( $user_id ) ) {
+		$link = add_query_arg(
+			array(
+				'action' => 'unsubscribe',
+				'nh'     => hash_hmac( 'sha1', "{$email_type}:{$user_id}", bp_email_get_salt() ),
+				'nt'     => $args['notification_type'],
+				'uid'    => $user_id,
+			),
+			$redirect_to
+		);
+
+	// Case where the recipient is not a member of the site.
+	} else if ( ! empty( $args['email_address'] ) ) {
+		$email_address = $args['email_address'];
+		$member_id     = (int) $args['member_id'];
+		$link          = add_query_arg(
+			array(
+				'action' => 'unsubscribe',
+				'nh'     => hash_hmac( 'sha1', "{$email_type}:{$email_address}", bp_email_get_salt() ),
+				'nt'     => $args['notification_type'],
+				'mid'    => $member_id,
+				'uem'    => $email_address,
+			),
+			$redirect_to
+		);
+	}
 
 	/**
 	 * Filters the unsubscribe link.
@@ -4360,6 +4430,24 @@ function bp_get_optouts( $args = array() ) {
 	return $optout_class::get( $args );
 }
 
+/**
+ * Check an email address to see if that individual has opted out.
+ *
+ * @since 8.0.0
+ *
+ * @param string $email_address Email address to check.
+ * @return bool True if the user has opted out, false otherwise.
+ */
+function bp_user_has_opted_out( $email_address = '' ) {
+	$optout_class = new BP_Optout();
+	$optout_id    = $optout_class->optout_exists(
+		array(
+			'email_address' => $email_address,
+		)
+	);
+	return (bool) $optout_id;
+}
+
 /**
  * Delete a BP_Optout by ID.
  *
diff --git src/bp-core/bp-core-template.php src/bp-core/bp-core-template.php
index 799a69cdc..e840a7cd6 100644
--- src/bp-core/bp-core-template.php
+++ src/bp-core/bp-core-template.php
@@ -2247,6 +2247,17 @@ function bp_is_settings_component() {
 	return (bool) bp_is_current_component( 'settings' );
 }
 
+/**
+ * Check whether the current page is an Invitations screen.
+ *
+ * @since 8.0.0
+ *
+ * @return bool True if the current page is an Invitations screen.
+ */
+function bp_is_members_invitations_screen() {
+	return (bool) bp_is_current_component( bp_get_members_invitations_slug() );
+}
+
 /**
  * Is the current component an active core component?
  *
@@ -2647,6 +2658,45 @@ function bp_is_user_settings_profile() {
 	return (bool) ( bp_is_user_settings() && bp_is_current_action( 'profile' ) );
 }
 
+/**
+ * Is the current page a user's community invitations page?
+ *
+ * Eg http://example.com/members/cassie/invitations/ (or a subpage thereof).
+ *
+ * @since 8.0.0
+ *
+ * @return bool True if the current page is a user's community invitations page.
+ */
+function bp_is_user_members_invitations() {
+	return (bool) ( bp_is_user() && bp_is_members_invitations_screen() );
+}
+
+/**
+ * Is the current page a user's List Invites page?
+ *
+ * Eg http://example.com/members/cassie/invitations/list-invites/.
+ *
+ * @since 8.0.0
+ *
+ * @return bool True if the current page is a user's List Invites page.
+ */
+function bp_is_user_members_invitations_list() {
+	return (bool) ( bp_is_user_members_invitations() && bp_is_current_action( 'list-invites' ) );
+}
+
+/**
+ * Is the current page a user's Send Invites page?
+ *
+ * Eg http://example.com/members/cassie/invitations/send-invites/.
+ *
+ * @since 8.0.0
+ *
+ * @return bool True if the current page is a user's Send Invites page.
+ */
+function bp_is_user_members_invitations_send_screen() {
+	return (bool) ( bp_is_user_members_invitations() && bp_is_current_action( 'send-invites' ) );
+}
+
 /** Groups ********************************************************************/
 
 /**
diff --git src/bp-core/bp-core-update.php src/bp-core/bp-core-update.php
index 6747c3ac5..03710213c 100644
--- src/bp-core/bp-core-update.php
+++ src/bp-core/bp-core-update.php
@@ -697,6 +697,10 @@ function bp_core_get_8_0_upgrade_email_schema( $emails ) {
 		$new_emails['core-user-activation'] = $emails['core-user-activation'];
 	}
 
+	if ( isset( $emails['bp-members-invitation'] ) ) {
+		$new_emails['bp-members-invitation'] = $emails['bp-members-invitation'];
+	}
+
 	return $new_emails;
 }
 
diff --git src/bp-core/classes/class-bp-admin.php src/bp-core/classes/class-bp-admin.php
index 1e10deab7..bbf945471 100644
--- src/bp-core/classes/class-bp-admin.php
+++ src/bp-core/classes/class-bp-admin.php
@@ -411,6 +411,12 @@ class BP_Admin {
 			register_setting( 'buddypress', 'bp-disable-cover-image-uploads', 'intval' );
 		}
 
+		// Community Invitations.
+		if ( bp_is_active( 'members', 'invitations' ) ) {
+			add_settings_field( 'bp-enable-members-invitations', __( 'Invitations', 'buddypress' ), 'bp_admin_setting_callback_members_invitations', 'buddypress', 'bp_members' );
+			register_setting( 'buddypress', 'bp-enable-members-invitations', 'intval' );
+		}
+
 		/* XProfile Section **************************************************/
 
 		if ( bp_is_active( 'xprofile' ) ) {
diff --git src/bp-core/classes/class-bp-invitation-manager.php src/bp-core/classes/class-bp-invitation-manager.php
index 0b7d2f009..a478c2c81 100644
--- src/bp-core/classes/class-bp-invitation-manager.php
+++ src/bp-core/classes/class-bp-invitation-manager.php
@@ -99,6 +99,11 @@ abstract class BP_Invitation_Manager {
 			return false;
 		}
 
+		// If an email address is specified, it must be a valid email address.
+		if ( $r['invitee_email'] && ! is_email( $r['invitee_email'] ) ) {
+			return false;
+		}
+
 		/**
 		 * Is this user allowed to extend invitations in this situation?
 		 *
@@ -157,7 +162,7 @@ abstract class BP_Invitation_Manager {
 	 * @param int   $invitation_id ID of invitation to send.
 	 * @param array $args          See BP_Invitation::mark_sent().
 	 *
-	 * @return int|bool The number of rows updated, or false on error.
+	 * @return bool The result of `run_send_action()`.
 	 */
 	public function send_invitation_by_id( $invitation_id = 0, $args = array() ) {
 		$updated = false;
@@ -195,11 +200,13 @@ abstract class BP_Invitation_Manager {
 		}
 
 		// Perform the send action.
-		$this->run_send_action( $invitation );
+		$success = $this->run_send_action( $invitation );
 
-		$updated = BP_Invitation::mark_sent( $invitation->id, $args );
+		if ( $success ) {
+			BP_Invitation::mark_sent( $invitation->id, $args );
+		}
 
-		return $updated;
+		return $success;
 	}
 
 	/**
@@ -309,7 +316,7 @@ abstract class BP_Invitation_Manager {
 	 * @param int   $request_id ID of request to send.
 	 * @param array $args       See BP_Invitation::mark_sent().
 	 *
-	 * @return int|bool The number of rows updated, or false on error.
+	 * @return bool The result of `run_send_action()`.
 	 */
 	public function send_request_notification_by_id( $request_id = 0, $args = array() ) {
 		$updated = false;
@@ -342,11 +349,13 @@ abstract class BP_Invitation_Manager {
 		}
 
 		// Perform the send action.
-		$this->run_send_action( $request );
+		$success = $this->run_send_action( $request );
 
-		$updated = BP_Invitation::mark_sent( $request->id, $args );
+		if ( $success ) {
+			BP_Invitation::mark_sent( $request->id, $args );
+		}
 
-		return $updated;
+		return $success;
 	}
 
 	/** Retrieve ******************************************************************/
@@ -383,6 +392,26 @@ abstract class BP_Invitation_Manager {
 		return BP_Invitation::get( $args );
 	}
 
+	/**
+	 * Get a count of the number of invitations that match provided filter parameters.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @see BP_Invitation::get_total_count() for a description of accepted parameters.
+	 *
+	 * @return int Total number of invitations.
+	 */
+	public function get_invitations_total_count( $args = array() ) {
+		// Default to returning invitations, not requests.
+		if ( empty( $args['type'] ) ) {
+			$args['type'] = 'invite';
+		}
+		// Use the class_name property value.
+		$args['class'] = $this->class_name;
+
+		return BP_Invitation::get_total_count( $args );
+	}
+
 	/**
 	 * Get requests, based on provided filter parameters.
 	 *
@@ -475,6 +504,7 @@ abstract class BP_Invitation_Manager {
 	 public function accept_invitation( $args = array() ) {
 
 		$r = bp_parse_args( $args, array(
+			'id'                => false,
 			'user_id'           => 0,
 			'invitee_email'     => '',
 			'item_id'           => null,
@@ -484,7 +514,7 @@ abstract class BP_Invitation_Manager {
 		), 'accept_invitation' );
 		$r['class'] = $this->class_name;
 
-		if ( ! ( ( $r['user_id'] || $r['invitee_email'] ) && $r['class'] && $r['item_id'] ) ) {
+		if ( ! $r['id'] && ! ( ( $r['user_id'] || $r['invitee_email'] ) && $r['class'] && $r['item_id'] ) ) {
 			return false;
 		}
 
@@ -703,6 +733,26 @@ abstract class BP_Invitation_Manager {
 		) );
 	}
 
+	/**
+	 * Delete an invitation by id.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param int $id ID of the invitation to delete.
+	 * @return int|bool Number of rows deleted on success, false on failure.
+	 */
+	public function delete_by_id( $id ) {
+		// Ensure that the invitation exists and was created by this class.
+		$invite = new BP_Invitation( $id );
+		if ( ! $invite->id || sanitize_key( $this->class_name ) !== $invite->class ) {
+			return false;
+		}
+
+		return BP_Invitation::delete_by_id( $id );
+	}
+
+
+
 	/**
 	 * This is where custom actions are added (in child classes)
 	 * to determine whether an invitation should be allowed.
diff --git src/bp-members/admin/bp-members-admin-classes.php src/bp-members/admin/bp-members-admin-classes.php
index 96e339e7a..4e2e79b54 100644
--- src/bp-members/admin/bp-members-admin-classes.php
+++ src/bp-members/admin/bp-members-admin-classes.php
@@ -12,6 +12,7 @@ defined( 'ABSPATH' ) || exit;
 
 if ( class_exists( 'WP_Users_List_Table' ) ) {
 	require dirname( dirname( __FILE__ ) ) . '/classes/class-bp-members-list-table.php';
+	require dirname( dirname( __FILE__ ) ) . '/classes/class-bp-members-invitations-list-table.php';
 }
 
 if ( class_exists( 'WP_MS_Users_List_Table' ) ) {
diff --git src/bp-members/bp-members-activity.php src/bp-members/bp-members-activity.php
index 8907d0a7e..a110cd6e7 100644
--- src/bp-members/bp-members-activity.php
+++ src/bp-members/bp-members-activity.php
@@ -56,10 +56,29 @@ add_action( 'bp_register_activity_actions', 'bp_members_register_activity_action
  * @return string $action
  */
 function bp_members_format_activity_action_new_member( $action, $activity ) {
-	$userlink = bp_core_get_userlink( $activity->user_id );
+	$userlink         = bp_core_get_userlink( $activity->user_id );
+	$inviter_userlink = false;
+	$invite_id        = bp_get_user_meta( $activity->user_id, 'accepted_members_invitation', true );
 
-	/* translators: %s: user link */
-	$action = sprintf( esc_html__( '%s became a registered member', 'buddypress' ), $userlink );
+	if ( $invite_id ) {
+		$invite = new BP_Invitation( (int) $invite_id );
+
+		if ( $invite->inviter_id ) {
+			$inviter_userlink = bp_core_get_userlink( $invite->inviter_id );
+		}
+	}
+
+	if ( $inviter_userlink ) {
+		$action = sprintf(
+			/* translators: 1: new user link. 2: inviter user link. */
+			esc_html__( '%1$s accepted an invitation from %2$s and became a registered member', 'buddypress' ),
+			$userlink,
+			$inviter_userlink
+		);
+	} else {
+		/* translators: %s: user link */
+		$action = sprintf( esc_html__( '%s became a registered member', 'buddypress' ), $userlink );
+	}
 
 	// Legacy filter - pass $user_id instead of $activity.
 	if ( has_filter( 'bp_core_activity_registered_member_action' ) ) {
@@ -69,12 +88,13 @@ function bp_members_format_activity_action_new_member( $action, $activity ) {
 	/**
 	 * Filters the formatted 'new member' activity actions.
 	 *
-	 * @since 2.2.0
+	 * @since 8.0.0
 	 *
-	 * @param string $action   Static activity action.
-	 * @param object $activity Activity object.
+	 * @param string $action    Static activity action.
+	 * @param object $activity  Activity object.
+	 * @param int    $invite_id The ID of the invite.
 	 */
-	return apply_filters( 'bp_members_format_activity_action_new_member', $action, $activity );
+	return apply_filters( 'bp_members_format_activity_action_new_member', $action, $activity, $invite_id );
 }
 
 /**
diff --git src/bp-members/bp-members-adminbar.php src/bp-members/bp-members-adminbar.php
index 10f784d09..282be654c 100644
--- src/bp-members/bp-members-adminbar.php
+++ src/bp-members/bp-members-adminbar.php
@@ -23,8 +23,9 @@ function bp_members_admin_bar_my_account_menu() {
 	global $wp_admin_bar;
 
 	// Bail if this is an ajax request.
-	if ( defined( 'DOING_AJAX' ) )
+	if ( wp_doing_ajax() ) {
 		return;
+	}
 
 	// Logged in user.
 	if ( is_user_logged_in() ) {
@@ -178,3 +179,61 @@ function bp_members_remove_edit_page_menu() {
 	}
 }
 add_action( 'add_admin_bar_menus', 'bp_members_remove_edit_page_menu' );
+
+/**
+ * Add the "Invitations" menu and submenus.
+ *
+ * @since 8.0.0
+ */
+function bp_members_admin_bar_add_invitations_menu() {
+	global $wp_admin_bar;
+
+	// Bail if this is an ajax request.
+	if ( wp_doing_ajax() ) {
+		return;
+	}
+
+	if ( is_user_logged_in() && bp_get_members_invitations_allowed() && ( bp_current_user_can( 'bp_members_send_invitation' ) || bp_members_invitations_user_has_sent_invites() ) ) {
+		$bp               = buddypress();
+		$invitations_link = trailingslashit( bp_loggedin_user_domain() . bp_get_members_invitations_slug() );
+
+		$wp_admin_bar->add_node(
+			array(
+				'id'     => $bp->my_account_menu_id . '-invitations',
+				'parent' => $bp->my_account_menu_id,
+				'title'  => __( 'Invitations', 'buddypress' ),
+				'href'   => $invitations_link,
+				'meta'   => array(
+					'class'  => 'ab-sub-secondary'
+				)
+			)
+		);
+
+		if ( bp_current_user_can( 'bp_members_send_invitation' ) ) {
+			$wp_admin_bar->add_node(
+				array(
+					'id'     => $bp->my_account_menu_id . '-invitations-send',
+					'parent' => $bp->my_account_menu_id . '-invitations',
+					'title'  => __( 'Send Invites', 'buddypress' ),
+					'href'   => $invitations_link,
+					'meta'   => array(
+						'class'  => 'ab-sub-secondary'
+					)
+				)
+			);
+		}
+
+		$wp_admin_bar->add_node(
+			array(
+				'id'     => $bp->my_account_menu_id . '-invitations-list',
+				'parent' => $bp->my_account_menu_id . '-invitations',
+				'title'  => __( 'Pending Invites', 'buddypress' ),
+				'href'   => $invitations_link . 'list-invites/',
+				'meta'   => array(
+					'class'  => 'ab-sub-secondary'
+				)
+			)
+		);
+	}
+}
+add_action( 'bp_setup_admin_bar', 'bp_members_admin_bar_add_invitations_menu', 90 );
diff --git src/bp-members/bp-members-filters.php src/bp-members/bp-members-filters.php
index 5575ebef2..fcdcf4fa3 100644
--- src/bp-members/bp-members-filters.php
+++ src/bp-members/bp-members-filters.php
@@ -127,3 +127,178 @@ function bp_members_edit_profile_url( $url, $user_id, $scheme = 'admin' ) {
 	return apply_filters( 'bp_members_edit_profile_url', $profile_link, $url, $user_id, $scheme );
 }
 add_filter( 'edit_profile_url', 'bp_members_edit_profile_url', 10, 3 );
+
+/**
+ * Filter the bp_user_can value to determine what the user can do in the members component.
+ *
+ * @since 8.0.0
+ *
+ * @param bool   $retval     Whether or not the current user has the capability.
+ * @param int    $user_id
+ * @param string $capability The capability being checked for.
+ * @param int    $site_id    Site ID. Defaults to the BP root blog.
+ * @param array  $args       Array of extra arguments passed.
+ *
+ * @return bool
+ */
+function bp_members_user_can_filter( $retval, $user_id, $capability, $site_id, $args = array() ) {
+
+	switch ( $capability ) {
+		case 'bp_members_manage_membership_requests':
+			$retval = bp_user_can( $user_id, 'bp_moderate' );
+			break;
+
+		case 'bp_members_send_invitation':
+			if ( bp_get_members_invitations_allowed() ) {
+				$retval = true;
+			}
+			break;
+
+		case 'bp_members_receive_invitation':
+			if ( bp_get_members_invitations_allowed() ) {
+				$retval = true;
+				// The invited user must not already be a member of the network.
+				if ( empty( $args['invitee_email'] ) || false !== get_user_by( 'email', $args['invitee_email'] ) ) {
+					$retval = false;
+				}
+				// The invited user must not have opted out from being contacted from this site.
+				if ( bp_user_has_opted_out( $args['invitee_email'] ) ) {
+					$retval = false;
+				}
+			}
+			break;
+	}
+
+	return $retval;
+}
+add_filter( 'bp_user_can', 'bp_members_user_can_filter', 10, 5 );
+
+/**
+ * Do not allow the new user to change the email address
+ * if they are accepting a community invitation.
+ *
+ * @since 8.0.0
+ *
+ * @param array  $attributes The field attributes.
+ * @param string $name       The field name.
+ *
+ * @return array $attributes The field attributes.
+ */
+function bp_members_invitations_make_registration_email_input_readonly_if_invite( $attributes, $name ) {
+	if ( 'email' === $name && bp_get_members_invitations_allowed() ) {
+		$invite = bp_get_members_invitation_from_request();
+		if ( $invite->id ) {
+			$attributes['readonly'] = 'readonly';
+		}
+	}
+	return $attributes;
+}
+add_filter( 'bp_get_form_field_attributes', 'bp_members_invitations_make_registration_email_input_readonly_if_invite', 10, 2 );
+
+/**
+ * Provide a more-specific welcome message if the new user
+ * is accepting a network invitation.
+ *
+ * @since 8.0.0
+ *
+ * @return string $message The message text.
+ */
+function bp_members_invitations_get_registration_welcome_message() {
+	$message = '';
+	if ( ! bp_get_members_invitations_allowed() ) {
+		return $message;
+	}
+	$invite = bp_get_members_invitation_from_request();
+	if ( ! $invite->id ) {
+		return $message;
+	}
+
+	// Fetch the display names of all inviters to personalize the welcome message.
+	$all_invites = bp_members_invitations_get_invites(
+		array(
+			'invitee_email' => $invite->invitee_email,
+			'invite_sent'   => 'sent',
+		)
+	);
+	$inviters = array();
+	foreach ( $all_invites as $inv ) {
+		$inviters[] = bp_core_get_user_displayname( $inv->inviter_id );
+	}
+
+	if ( ! empty( $inviters ) ) {
+		$message = sprintf( _n( 'Welcome! You&#8217;ve been invited to join the site by the following user: %s. ', 'Welcome! You&#8217;ve been invited to join the site by the following users: %s. ', count( $inviters ), 'buddypress' ), implode( ', ', $inviters ) );
+	} else {
+		$message = __( 'Welcome! You&#8217;ve been invited to join the site. ', 'buddypress' );
+	}
+	return $message;
+}
+
+/**
+ * Provide a more-specific "registration is disabled" message
+ * if registration is available by invitation only.
+ * Also provide failure note if new user is trying to accept
+ * a network invitation but there's a problem.
+ *
+ * @since 8.0.0
+ *
+ * @return string $message The message text.
+ */
+function bp_members_invitations_get_modified_registration_disabled_message() {
+	$message = '';
+	if ( bp_get_members_invitations_allowed() ) {
+		$message = __( 'Member registration is allowed by invitation only.', 'buddypress' );
+		// Is the user trying to accept an invitation but something is wrong?
+		if ( ! empty( $_GET['inv'] ) ) {
+			$message .= __( ' It looks like there is a problem with your invitation. Please try again.', 'buddypress' );
+		}
+	}
+	return $message;
+}
+
+/**
+ * Sanitize the invitation property output.
+ *
+ * @since 8.0.0
+ *
+ * @param int|string $value    The value for the requested property.
+ * @param string     $property The name of the requested property.
+ * @param string     $context  The context of display.
+ * @return int|string          The sanitized value.
+ */
+function bp_members_sanitize_invitation_property( $value = '', $property = '', $context = 'html' ) {
+	if ( ! $property ) {
+		return '';
+	}
+
+	switch ( $property ) {
+		case 'id':
+		case 'user_id':
+		case 'item_id':
+		case 'secondary_item_id':
+			$value = absint( $value );
+			break;
+		case 'invite_sent':
+		case 'accepted':
+			$value = absint( $value ) ? __( 'Yes', 'buddypress' ) : __( 'No', 'buddypress' );
+			$value = 'attribute' === $context ? esc_attr( $value ) : esc_html( $value );
+			break;
+		case 'invitee_email':
+			$value = sanitize_email( $value );
+			break;
+		case 'content':
+			$value = wp_kses( $value, array() );
+			$value = wptexturize( $value );
+			break;
+		case 'date_modified':
+			$value = mysql2date( 'Y/m/d g:i:s a', $value );
+			$value = 'attribute' === $context ? esc_attr( $value ) : esc_html( $value );
+			break;
+
+		default:
+			$value = 'attribute' === $context ? esc_attr( $value ) : esc_html( $value );
+			break;
+	}
+
+	return $value;
+}
+add_filter( 'bp_the_members_invitation_property', 'bp_members_sanitize_invitation_property', 10, 3 );
diff --git src/bp-members/bp-members-functions.php src/bp-members/bp-members-functions.php
index 347614fc8..b6940ebb1 100644
--- src/bp-members/bp-members-functions.php
+++ src/bp-members/bp-members-functions.php
@@ -3342,3 +3342,298 @@ function bp_send_welcome_email( $user_id = 0 ) {
 	bp_send_email( 'core-user-activation', $user_id, array( 'tokens' => $welcome_tokens ) );
 }
 add_action( 'bp_core_activated_user', 'bp_send_welcome_email', 10, 1 );
+
+/**
+ * Get invitations to the BP community filtered by arguments.
+ *
+ * @since 8.0.0
+ *
+ * @param array $args     Invitation arguments.
+ *                        See BP_Invitation::get() for list.
+ *
+ * @return array $invites     Matching BP_Invitation objects.
+ */
+function bp_members_invitations_get_invites( $args = array() ) {
+	$invites_class = new BP_Members_Invitation_Manager();
+	return $invites_class->get_invitations( $args );
+}
+
+/**
+ * Check whether a user has sent any community invitations.
+ *
+ * @since 8.0.0
+ *
+ * @param int $user_id ID of user to check for invitations sent by.
+ *                     Defaults to the current user's ID.
+ *
+ * @return bool $invites True if user has sent invites.
+ */
+function bp_members_invitations_user_has_sent_invites( $user_id = 0 ) {
+	if ( 0 === $user_id ) {
+		$user_id = bp_loggedin_user_id();
+		if ( ! $user_id ) {
+			return false;
+		}
+	}
+	$invites_class = new BP_Members_Invitation_Manager();
+	$args = array(
+		'inviter_id' => $user_id,
+	);
+	return (bool) $invites_class->invitation_exists( $args );
+}
+
+/**
+ * Invite a user to a BP community.
+ *
+ * @since 8.0.0
+ *
+ * @param array|string $args {
+ *     Array of arguments.
+ *     @type int    $invitee_email Email address of the user being invited.
+ *     @type int    $network_id    ID of the network to which the user is being invited.
+ *     @type int    $inviter_id    Optional. ID of the inviting user. Default:
+ *                                 ID of the logged-in user.
+ *     @type string $date_modified Optional. Modified date for the invitation.
+ *                                 Default: current date/time.
+ *     @type string $content       Optional. Message to invitee.
+ *     @type bool   $send_invite   Optional. Whether the invitation should be
+ *                                 sent now. Default: false.
+ * }
+ * @return bool True on success, false on failure.
+ */
+function bp_members_invitations_invite_user( $args ) {
+	$r = bp_parse_args( $args, array(
+		'invitee_email' => '',
+		'network_id'    => get_current_network_id(),
+		'inviter_id'    => bp_loggedin_user_id(),
+		'date_modified' => bp_core_current_time(),
+		'content'       => '',
+		'send_invite'   => 0
+	), 'community_invite_user' );
+
+	$inv_args = array(
+		'invitee_email' => $r['invitee_email'],
+		'item_id'       => $r['network_id'],
+		'inviter_id'    => $r['inviter_id'],
+		'date_modified' => $r['date_modified'],
+		'content'       => $r['content'],
+		'send_invite'   => $r['send_invite']
+	);
+
+	// Create the invitataion.
+	$invites_class = new BP_Members_Invitation_Manager();
+	$created       = $invites_class->add_invitation( $inv_args );
+
+	/**
+	 * Fires after the creation of a new network invite.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param array    $r       Array of parsed arguments for the network invite.
+	 * @param int|bool $created The ID of the invitation or false if it couldn't be created.
+	 */
+	do_action( 'bp_members_invitations_invite_user', $r, $created );
+
+	return $created;
+}
+
+/**
+ * Resend a membership invitation email by id.
+ *
+ * @since 8.0.0
+ *
+ * @param int $id ID of the invitation to resend.
+ * @return bool True on success, false on failure.
+ */
+function bp_members_invitation_resend_by_id( $id = 0 ) {
+
+	// Find the invitation before deleting it.
+	$existing_invite = new BP_Invitation( $id );
+	$invites_class   = new BP_Members_Invitation_Manager();
+	$success         = $invites_class->send_invitation_by_id( $id );
+
+	if ( ! $success ) {
+		return $success;
+	}
+
+	/**
+	 * Fires after the re-sending of a network invite.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param BP_Invitation $existing_invite The invitation that was resent.
+	 */
+	do_action( 'bp_members_invitations_resend_invitation', $existing_invite );
+
+	return $success;
+}
+
+/**
+ * Delete a membership invitation by id.
+ *
+ * @since 8.0.0
+ *
+ * @param int $id ID of the invitation to delete.
+ * @return int|bool Number of rows deleted on success, false on failure.
+ */
+function bp_members_invitations_delete_by_id( $id = 0 ) {
+
+	// Find the invitation before deleting it.
+	$existing_invite = new BP_Invitation( $id );
+	$invites_class   = new BP_Members_Invitation_Manager();
+	$success         = $invites_class->delete_by_id( $id );
+
+	if ( ! $success ) {
+		return $success;
+	}
+
+	// Run a different action depending on the status of the invite.
+	if ( ! $existing_invite->invite_sent ) {
+		/**
+		 * Fires after the deletion of an unsent community invite.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param BP_Invitation $existing_invite The invitation to be deleted.
+		 */
+		do_action( 'bp_members_invitations_canceled_invitation', $existing_invite );
+	} else if ( ! $existing_invite->accepted ) {
+		/**
+		 * Fires after the deletion of a sent, but not yet accepted, community invite.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param BP_Invitation $existing_invite The invitation to be deleted.
+		 */
+		do_action( 'bp_members_invitations_revoked_invitation', $existing_invite );
+	} else {
+		/**
+		 * Fires after the deletion of a sent and accepted community invite.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param BP_Invitation $existing_invite The invitation to be deleted.
+		 */
+		do_action( 'bp_members_invitations_deleted_invitation', $existing_invite );
+	}
+
+	return $success;
+}
+
+/**
+ * Delete a membership invitation.
+ *
+ * @since 8.0.0
+ *
+ * @param intring $args {
+ *     Array of arguments.
+ *     @type int|array $id            Id(s) of the invitation(s) to remove.
+ *     @type int       $invitee_email Email address of the user being invited.
+ *     @type int       $network_id    ID of the network to which the user is being invited.
+ *     @type int       $inviter_id    ID of the inviting user.
+ *     @type int       $accepted      Whether the invitation has been accepted yet.
+ *     @type int       $invite_sent   Whether the invitation has been sent yet.
+ * }
+ * @return bool True if all were deleted.
+ */
+function bp_members_invitations_delete_invites( $args ) {
+	$r = bp_parse_args( $args, array(
+		'id'            => 0,
+ 		'invitee_email' => '',
+		'network_id'    => get_current_network_id(),
+		'inviter_id'    => null,
+		'accepted'      => null,
+		'invite_sent'   => null
+	), 'community_invitation_delete_invites' );
+
+	$inv_args = array(
+		'id'            => $r['id'],
+		'invitee_email' => $r['invitee_email'],
+		'item_id'       => $r['network_id'],
+		'inviter_id'    => $r['inviter_id'],
+	);
+
+	// Find the invitation(s).
+	$invites       = bp_members_invitations_get_invites( $inv_args );
+	$total_count   = count( $invites );
+
+	// Loop through, deleting each invitation.
+	$deleted = 0;
+	foreach ( $invites as $invite ) {
+		$success = bp_members_invitations_delete_by_id( $invite->id );
+		if ( $success ) {
+			$deleted++;
+		}
+	}
+
+	return $deleted === $total_count;
+}
+
+/**
+ * Get hash based on details of a membership invitation and the inviter.
+ *
+ * @since 8.0.0
+ *
+ * @param BP_Invitation object $invitation Invitation to create hash from.
+ *
+ * @return string $hash Calculated sha1 hash.
+ */
+function bp_members_invitations_get_hash( BP_Invitation $invitation ) {
+	$hash = false;
+
+	if ( ! empty( $invitation->id ) ) {
+		$inviter_ud = get_userdata( $invitation->inviter_id );
+		if ( $inviter_ud ) {
+			/*
+			 * Use some inviter details as part of the hash so that invitations from
+			 * users who are subsequently marked as spam will be invalidated.
+			 */
+			$hash = wp_hash( "{$invitation->inviter_id}:{$invitation->invitee_email}:{$inviter_ud->user_status}:{$inviter_ud->user_registered}" );
+		}
+	}
+
+	// If there's a problem, return a string that will change and thus fail.
+	if ( ! $hash ) {
+		$hash = wp_generate_password( 32, false );
+	}
+
+	/**
+	 * Filters the hash calculated by the invitation details.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param string $hash Calculated sha1 hash.
+	 * @param BP_Invitation object $invitation Invitation hash was created from.
+	 */
+	return apply_filters( 'bp_members_invitations_get_hash', $hash, $invitation );
+}
+
+/**
+ * Get the current invitation specified by the $_GET parameters.
+ *
+ * @since 8.0.0
+ *
+ * @return BP_Invitation $invite Invitation specified by the $_GET parameters.
+ */
+function bp_get_members_invitation_from_request() {
+	$invites_class = new BP_Members_Invitation_Manager();
+	$invite        = $invites_class->get_by_id( 0 );
+
+	if ( bp_get_members_invitations_allowed() && ! empty( $_GET['inv'] ) ) {
+		// Check to make sure the passed hash matches a calculated hash.
+		$maybe_invite = $invites_class->get_by_id( absint( $_GET['inv'] ) );
+		$hash = bp_members_invitations_get_hash( $maybe_invite );
+		if ( $_GET['ih'] === $hash ) {
+			$invite = $maybe_invite;
+		}
+	}
+
+	/**
+	 * Filters the invitation specified by the $_GET parameters.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param BP_Invitation $invite Invitation specified by the $_GET parameters.
+	 */
+	return apply_filters( 'bp_get_members_invitation_from_request', $invite );
+}
diff --git src/bp-members/bp-members-invitations.php src/bp-members/bp-members-invitations.php
new file mode 100644
index 000000000..2e1b5458e
--- /dev/null
+++ src/bp-members/bp-members-invitations.php
@@ -0,0 +1,141 @@
+<?php
+/**
+ * BuddyPress Membersip Invitations
+ *
+ * @package BuddyPress
+ * @subpackage MembersInvitations
+ * @since 8.0.0
+ */
+
+// Exit if accessed directly.
+defined( 'ABSPATH' ) || exit;
+
+function bp_members_invitations_setup_nav() {
+	if ( ! bp_get_members_invitations_allowed() ) {
+		return;
+	}
+
+	$user_has_access  = bp_user_has_access();
+	$user_can_send    = bp_user_can( bp_displayed_user_id(), 'bp_members_send_invitation' );
+	$user_has_invites = bp_members_invitations_user_has_sent_invites( bp_displayed_user_id() );
+
+	/* Add 'Invitations' to the main user profile navigation */
+	bp_core_new_nav_item(
+		array(
+			'name'                    => __( 'Invitations', 'buddypress' ),
+			'slug'                    => bp_get_members_invitations_slug(),
+			'position'                => 80,
+			'screen_function'         => 'members_screen_send_invites',
+			'default_subnav_slug'     => ( $user_can_send && bp_is_my_profile() ) ? 'send-invites' : 'list-invites',
+			'show_for_displayed_user' => $user_has_access && ( $user_can_send || $user_has_invites )
+		)
+	);
+
+	$parent_link = trailingslashit( bp_displayed_user_domain() . bp_get_members_invitations_slug() );
+
+	/* Create two subnav items for community invitations */
+	bp_core_new_subnav_item(
+		array(
+			'name'            => __( 'Send Invites', 'buddypress' ),
+			'slug'            => 'send-invites',
+			'parent_slug'     => bp_get_members_invitations_slug(),
+			'parent_url'      => $parent_link,
+			'screen_function' => 'members_screen_send_invites',
+			'position'        => 10,
+			'user_has_access' => $user_has_access && $user_can_send && bp_is_my_profile()
+		)
+	);
+
+	bp_core_new_subnav_item(
+		array(
+			'name'            => __( 'Pending Invites', 'buddypress' ),
+			'slug'            => 'list-invites',
+			'parent_slug'     => bp_get_members_invitations_slug(),
+			'parent_url'      => $parent_link,
+			'screen_function' => 'members_screen_list_sent_invites',
+			'position'        => 20,
+			'user_has_access' => $user_has_access && ( $user_can_send || $user_has_invites )
+		)
+	);
+}
+add_action( 'bp_setup_nav', 'bp_members_invitations_setup_nav' );
+
+/**
+ * When a user joins the network via an invitation, skip sending the activation email.
+ *
+ * @param bool   $send           Whether or not to send the activation key.
+ * @param int    $user_id        User ID to send activation key to.
+ * @param string $user_email     User email to send activation key to.
+ * @param string $activation_key Activation key to be sent.
+ * @param array  $usermeta       Miscellaneous metadata about the user (blog-specific
+ *                               signup data, xprofile data, etc).
+ */
+function bp_members_invitations_cancel_activation_email( $send, $user_id, $user_email, $activation_key, $usermeta ) {
+	$invite = bp_members_invitations_get_invites(
+		array(
+			'invitee_email' => $user_email,
+			'invite_sent'   => 'sent'
+		)
+	);
+
+	if ( $invite ) {
+		$send = false;
+	}
+
+	return $send;
+}
+add_filter( 'bp_core_signup_send_activation_key', 'bp_members_invitations_cancel_activation_email', 10, 5 );
+
+/**
+ * When a user joins the network via an invitation:
+ * - mark all invitations and requests as accepted
+ * - activate the user upon signup
+ *
+ * @param bool|WP_Error   $user_id       True on success, WP_Error on failure.
+ * @param string          $user_login    Login name requested by the user.
+ * @param string          $user_password Password requested by the user.
+ * @param string          $user_email    Email address requested by the user.
+ */
+function bp_members_invitations_complete_signup( $user_id, $user_login, $user_password, $user_email ) {
+	if ( ! $user_id ) {
+		return;
+	}
+
+	// Check to see if this signup is the result of a valid invitation.
+	$invite = bp_get_members_invitation_from_request();
+	if ( ! $invite->id ) {
+		return;
+	}
+
+	// Accept the invitation.
+	$invites_class = new BP_Members_Invitation_Manager();
+	$args          = array(
+		'id' => $invite->id,
+	);
+	$invites_class->accept_invitation( $args );
+
+	// User has already verified their email by responding to the invitation, so we can activate.
+	$key = bp_get_user_meta( $user_id, 'activation_key', true );
+	if ( $key ) {
+		/**
+		 * Filters the activation signup.
+		 *
+		 * @since 1.1.0
+		 *
+		 * @param bool|int $value Value returned by activation.
+		 *                        Integer on success, boolean on failure.
+		 */
+		$user = apply_filters( 'bp_core_activate_account', bp_core_activate_signup( $key ) );
+
+		// If there were errors, add a message and redirect.
+		if ( ! empty( $user->errors ) ) {
+			bp_core_add_message( $user->get_error_message(), 'error' );
+			bp_core_redirect( trailingslashit( bp_get_root_domain() . '/' . $bp->pages->activate->slug ) );
+		}
+
+		bp_core_add_message( __( 'Your account is now active!', 'buddypress' ) );
+		bp_core_redirect( add_query_arg( 'activated', '1', bp_get_activation_page() ) );
+	}
+}
+add_action( 'bp_core_signup_user', 'bp_members_invitations_complete_signup', 10, 4 );
+
diff --git src/bp-members/bp-members-notifications.php src/bp-members/bp-members-notifications.php
new file mode 100644
index 000000000..23ee17a77
--- /dev/null
+++ src/bp-members/bp-members-notifications.php
@@ -0,0 +1,172 @@
+<?php
+/**
+ * BuddyPress Members Activity Functions.
+ *
+ * These functions handle the recording, deleting and formatting of activity
+ * for the user and for this specific component.
+ *
+ * @package BuddyPress
+ * @subpackage MembersNotifications
+ * @since 8.0.0
+ */
+
+// Exit if accessed directly.
+defined( 'ABSPATH' ) || exit;
+
+/**
+ * Notification formatting callback for bp-members notifications.
+ *
+ * @since 8.0.0
+ *
+ * @param string $action            The kind of notification being rendered.
+ * @param int    $item_id           The primary item ID.
+ * @param int    $secondary_item_id The secondary item ID.
+ * @param int    $total_items       The total number of messaging-related notifications
+ *                                  waiting for the user.
+ * @param string $format            'string' for BuddyBar-compatible notifications;
+ *                                  'array' for WP Toolbar. Default: 'string'.
+ * @return array|string
+ */
+function members_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) {
+
+	switch ( $action ) {
+		case 'accepted_invitation':
+
+			// Set up the string and the filter.
+			if ( (int) $total_items > 1 ) {
+				$link = bp_get_members_directory_permalink();
+				/* translators: %d: the number of new users */
+				$text = sprintf( __( '%d members accepted your membership invitations', 'buddypress' ), (int) $total_items );
+				$amount = 'multiple';
+			} else {
+				$link = bp_core_get_user_domain( $item_id );
+				/* translators: %s: new user name */
+				$text = sprintf( __( '%s accepted your membership invitation', 'buddypress' ),  bp_core_get_user_displayname( $item_id ) );
+				$amount = 'single';
+			}
+
+			break;
+	}
+
+	// Return either an HTML link or an array, depending on the requested format.
+	if ( 'string' == $format ) {
+
+		/**
+		 * Filters the format of members notifications based on type and amount * of notifications pending.
+		 *
+		 * This is a variable filter that has four possible versions.
+		 * The possible versions are:
+		 *   - bp_members_single_accepted_invitation_notification
+		 *   - bp_members_multiple_accepted_invitation_notification
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param string|array $value             Depending on format, an HTML link to new requests profile tab or array with link and text.
+		 * @param int          $total_items       The total number of messaging-related notifications waiting for the user.
+		 * @param int          $item_id           The primary item ID.
+		 * @param int          $secondary_item_id The secondary item ID.
+		 */
+		$return = apply_filters( 'bp_members_' . $amount . '_'. $action . '_notification', '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>', (int) $total_items, $item_id, $secondary_item_id );
+	} else {
+		/** This filter is documented in bp-members/bp-members-notifications.php */
+		$return = apply_filters( 'bp_members_' . $amount . '_'. $action . '_notification', array(
+			'link' => $link,
+			'text' => $text
+		), (int) $total_items, $item_id, $secondary_item_id );
+	}
+
+	/**
+	 * Fires at the end of the bp-members notification format callback.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param string       $action            The kind of notification being rendered.
+	 * @param int          $item_id           The primary item ID.
+	 * @param int          $secondary_item_id The secondary item ID.
+	 * @param int          $total_items       The total number of members-related notifications
+	 *                                        waiting for the user.
+	 * @param array|string $return            Notification text string or array of link and text.
+	 */
+	do_action( 'members_format_notifications', $action, $item_id, $secondary_item_id, $total_items, $return );
+
+	return $return;
+}
+
+/**
+ * Notify one use that another user has accepted their site membership invitation.
+ *
+ * @since 8.0.0
+ *
+ * @param BP_Invitation $invite     Invitation that was accepted.
+ * @param WP_user       $new_user   User who accepted the membership invite.
+ * @param int           $inviter_id ID of the user who invited this user to the site.
+ */
+function bp_members_invitations_accepted_invitation_notification( $invite, $new_user, $inviter_id ) {
+
+	$res = bp_notifications_add_notification( array(
+		'user_id'           => $inviter_id,
+		'item_id'           => $new_user->ID,
+		'secondary_item_id' => $invite->id,
+		'component_name'    => buddypress()->members->id,
+		'component_action'  => 'accepted_invitation',
+		'date_notified'     => bp_core_current_time(),
+		'is_new'            => 1,
+	) );
+}
+add_action( 'community_membership_invite_accepted', 'bp_members_invitations_accepted_invitation_notification', 10, 3 );
+
+/**
+ * Add Friends-related settings to the Settings > Notifications page.
+ *
+ * @since 8.0.0
+ */
+function members_screen_notification_settings() {
+
+	// Bail early if invitations are not allowed--they are the only members notification so far.
+	if ( ! bp_get_members_invitations_allowed () ) {
+		return;
+	}
+
+	if ( ! $allow_acceptance_emails = bp_get_user_meta( bp_displayed_user_id(), 'notification_members_invitation_accepted', true ) )
+		$allow_acceptance_emails = 'yes';
+	?>
+
+	<table class="notification-settings" id="members-notification-settings">
+		<thead>
+			<tr>
+				<th class="icon"></th>
+				<th class="title"><?php _ex( 'Members', 'Member settings on notification settings page', 'buddypress' ) ?></th>
+				<th class="yes"><?php _e( 'Yes', 'buddypress' ) ?></th>
+				<th class="no"><?php _e( 'No', 'buddypress' )?></th>
+			</tr>
+		</thead>
+
+		<tbody>
+			<tr id="members-notification-settings-invitation_accepted">
+				<td></td>
+				<td><?php _ex( 'Someone accepts your membership invitation', 'Member settings on notification settings page', 'buddypress' ) ?></td>
+				<td class="yes"><input type="radio" name="notifications[notification_members_invitation_accepted]" id="notification-members-invitation-accepted-yes" value="yes" <?php checked( $allow_acceptance_emails, 'yes', true ) ?>/><label for="notification-members-invitation-accepted-yes" class="bp-screen-reader-text"><?php
+					/* translators: accessibility text */
+					_e( 'Yes, send email', 'buddypress' );
+				?></label></td>
+				<td class="no"><input type="radio" name="notifications[notification_members_invitation_accepted]" id="notification-members-invitation-accepted-no" value="no" <?php checked( $allow_acceptance_emails, 'no', true ) ?>/><label for="notification-members-invitation-accepted-no" class="bp-screen-reader-text"><?php
+					/* translators: accessibility text */
+					_e( 'No, do not send email', 'buddypress' );
+				?></label></td>
+			</tr>
+
+			<?php
+
+			/**
+			 * Fires after the last table row on the members notification screen.
+			 *
+			 * @since 1.0.0
+			 */
+			do_action( 'members_screen_notification_settings' ); ?>
+
+		</tbody>
+	</table>
+
+<?php
+}
+add_action( 'bp_notification_settings', 'members_screen_notification_settings' );
diff --git src/bp-members/bp-members-template.php src/bp-members/bp-members-template.php
index 541b27479..b7f9c9afb 100644
--- src/bp-members/bp-members-template.php
+++ src/bp-members/bp-members-template.php
@@ -274,6 +274,34 @@ function bp_activate_slug() {
 		return apply_filters( 'bp_get_activate_slug', $slug );
 	}
 
+/**
+ * Output the members invitation pane slug.
+ *
+ * @since 8.0.0
+ *
+ */
+function bp_members_invitations_slug() {
+	echo bp_get_members_invitations_slug();
+}
+	/**
+	 * Return the members invitations root slug.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @return string
+	 */
+	function bp_get_members_invitations_slug() {
+
+		/**
+		 * Filters the Members invitations pane root slug.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param string $slug Members invitations pane root slug.
+		 */
+		return apply_filters( 'bp_get_members_invitations_slug', _x( 'invitations', 'Member profile invitations pane URL base', 'buddypress' ) );
+	}
+
 /**
  * Initialize the members loop.
  *
@@ -2381,8 +2409,14 @@ function bp_signup_email_value() {
 	 */
 	function bp_get_signup_email_value() {
 		$value = '';
-		if ( isset( $_POST['signup_email'] ) )
+		if ( isset( $_POST['signup_email'] ) ) {
 			$value = $_POST['signup_email'];
+		} else if ( bp_get_members_invitations_allowed() ) {
+			$invite = bp_get_members_invitation_from_request();
+			if ( $invite ) {
+				$value = $invite->invitee_email;
+			}
+		}
 
 		/**
 		 * Filters the email address submitted during signup.
@@ -2755,6 +2789,24 @@ function bp_signup_allowed() {
 		return apply_filters( 'bp_get_signup_allowed', (bool) bp_get_option( 'users_can_register' ) );
 	}
 
+/**
+ * Are users allowed to invite users to join this site?
+ *
+ * @since 8.0.0
+ *
+ * @return bool
+ */
+function bp_get_members_invitations_allowed() {
+	/**
+	 * Filters whether or not community invitations are allowed.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param bool $allowed Whether or not community invitations are allowed.
+	 */
+	return apply_filters( 'bp_get_members_invitations_allowed', bp_is_active( 'members', 'invitations' ) && (bool) bp_get_option( 'bp-enable-members-invitations' ) );
+}
+
 /**
  * Hook member activity feed to <head>.
  *
@@ -2869,3 +2921,559 @@ function bp_avatar_delete_link() {
 		 */
 		return apply_filters( 'bp_get_avatar_delete_link', wp_nonce_url( bp_displayed_user_domain() . bp_get_profile_slug() . '/change-avatar/delete-avatar/', 'bp_delete_avatar_link' ) );
 	}
+
+
+/** The Members Invitations Loop ******************************************************************/
+
+/**
+ * Initialize the community invitations loop.
+ *
+ * Based on the $args passed, bp_has_invitations() populates
+ * buddypress()->invitations->query_loop global, enabling the use of BP
+ * templates and template functions to display a list of invitations.
+ *
+ * @since 8.0.0
+ *
+ * @param array|string $args {
+ *     Arguments for limiting the contents of the invitations loop. Can be
+ *     passed as an associative array, or as a URL query string.
+ *
+ *     See {@link BP_Invitations_Invitation::get()} for detailed
+ *     information on the arguments.  In addition, also supports:
+ *
+ *     @type int    $max      Optional. Max items to display. Default: false.
+ *     @type string $page_arg URL argument to use for pagination.
+ *                            Default: 'ipage'.
+ * }
+ * @return bool
+ */
+function bp_has_members_invitations( $args = '' ) {
+
+	// Get the user ID.
+	if ( bp_displayed_user_id() ) {
+		$user_id = bp_displayed_user_id();
+	} else {
+		$user_id = bp_loggedin_user_id();
+	}
+
+	// Set the search terms (by default an empty string to get all notifications)
+	$search_terms = '';
+
+	if ( isset( $_REQUEST['s'] ) ) {
+		$search_terms = stripslashes( $_REQUEST['s'] );
+	}
+
+	// Parse the args.
+	$r = bp_parse_args( $args, array(
+		'id'                => false,
+		'inviter_id'        => $user_id,
+		'invitee_email'     => false,
+		'item_id'           => false,
+		'type'              => 'invite',
+		'invite_sent'       => 'all',
+		'accepted'          => 'pending',
+		'search_terms'      => $search_terms,
+		'order_by'          => 'date_modified',
+		'sort_order'        => 'DESC',
+		'page'              => 1,
+		'per_page'          => 25,
+		'fields'            => 'all',
+
+		// These are additional arguments that are not available in
+		// BP_Invitations_Invitation::get().
+		'page_arg'          => 'ipage',
+	), 'has_community_invitations' );
+
+	// Get the notifications.
+	$query_loop = new BP_Members_Invitations_Template( $r );
+
+	// Setup the global query loop.
+	buddypress()->members->invitations->query_loop = $query_loop;
+
+	/**
+	 * Filters whether or not the user has network invitations to display.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param bool                      $value      Whether or not there are network invitations to display.
+	 * @param BP_Notifications_Template $query_loop BP_Members_Invitations_Template object instance.
+	 * @param array                     $r          Array of arguments passed into the BP_Members_Invitations_Template class.
+	 */
+	return apply_filters( 'bp_has_members_invitations', $query_loop->has_invitations(), $query_loop, $r );
+}
+
+/**
+ * Get the network invitations returned by the template loop.
+ *
+ * @since 8.0.0
+ *
+ * @return array List of network invitations.
+ */
+function bp_the_members_invitations() {
+	return buddypress()->members->invitations->query_loop->invitations();
+}
+
+/**
+ * Get the current network invitation object in the loop.
+ *
+ * @since 8.0.0
+ *
+ * @return object The current network invitation within the loop.
+ */
+function bp_the_members_invitation() {
+	return buddypress()->members->invitations->query_loop->the_invitation();
+}
+
+/**
+ * Output the pagination count for the current network invitations loop.
+ *
+ * @since 8.0.0
+ */
+function bp_members_invitations_pagination_count() {
+	echo bp_get_members_invitations_pagination_count();
+}
+	/**
+	 * Return the pagination count for the current network invitation loop.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @return string HTML for the pagination count.
+	 */
+	function bp_get_members_invitations_pagination_count() {
+		$query_loop = buddypress()->members->invitations->query_loop;
+		$start_num  = intval( ( $query_loop->pag_page - 1 ) * $query_loop->pag_num ) + 1;
+		$from_num   = bp_core_number_format( $start_num );
+		$to_num     = bp_core_number_format( ( $start_num + ( $query_loop->pag_num - 1 ) > $query_loop->total_invitation_count ) ? $query_loop->total_invitation_count : $start_num + ( $query_loop->pag_num - 1 ) );
+		$total      = bp_core_number_format( $query_loop->total_invitation_count );
+
+		if ( 1 == $query_loop->total_invitation_count ) {
+			$pag = __( 'Viewing 1 invitation', 'buddypress' );
+		} else {
+			/* translators: 1: notification from number. 2: notification to number. 3: total notifications. */
+			$pag = sprintf( _n( 'Viewing %1$s - %2$s of %3$s invitation', 'Viewing %1$s - %2$s of %3$s invitations', $query_loop->total_invitation_count, 'buddypress' ), $from_num, $to_num, $total );
+		}
+
+		/**
+		 * Filters the pagination count for the current network invitation loop.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param string $pag HTML for the pagination count.
+		 */
+		return apply_filters( 'bp_get_members_invitations_pagination_count', $pag );
+	}
+
+/**
+ * Output the pagination links for the current network invitation loop.
+ *
+ * @since 8.0.0
+ */
+function bp_members_invitations_pagination_links() {
+	echo bp_get_members_invitations_pagination_links();
+}
+	/**
+	 * Return the pagination links for the current network invitations loop.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @return string HTML for the pagination links.
+	 */
+	function bp_get_members_invitations_pagination_links() {
+
+		/**
+		 * Filters the pagination links for the current network invitations loop.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param string $pag_links HTML for the pagination links.
+		 */
+		return apply_filters( 'bp_get_members_invitations_pagination_links', buddypress()->members->invitations->query_loop->pag_links );
+	}
+
+/**
+ * Output the requested property of the invitation currently being iterated on.
+ *
+ * @since 8.0.0
+ *
+ * @param string $property The name of the property to display.
+ * @param string $context  The context of display.
+ *                         Possible values are 'attribute' and 'html'.
+ */
+function bp_the_members_invitation_property( $property = '', $context = 'html' ) {
+	if ( ! $property ) {
+		return;
+	}
+
+	/**
+	 * Use this filter to sanitize the output.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param int|string $value    The value for the requested property.
+	 * @param string     $property The name of the requested property.
+	 * @param string     $context  The context of display.
+	 */
+	echo apply_filters( 'bp_the_members_invitation_property', bp_get_the_members_invitation_property( $property ), $property, $context );
+}
+	/**
+	 * Return the value for a property of the network invitation currently being iterated on.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @return int ID of the current network invitation.
+	 */
+	function bp_get_the_members_invitation_property( $property = 'id' ) {
+
+		switch ( $property ) {
+			case 'id':
+			case 'user_id':
+			case 'item_id':
+			case 'secondary_item_id':
+			case 'invite_sent':
+			case 'accepted':
+				$value = 0;
+				break;
+			case 'invitee_email':
+			case 'type':
+			case 'content':
+			case 'date_modified':
+				$value = '';
+				break;
+			default:
+				// A known property has not been specified.
+				$property = null;
+				$value = '';
+				break;
+		}
+
+		if ( isset( buddypress()->members->invitations->query_loop->invitation->{$property} ) ) {
+			$value = buddypress()->members->invitations->query_loop->invitation->{$property};
+		}
+
+		/**
+		 * Filters the property of the network invitation currently being iterated on.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param int|string $value Property value of the network invitation being iterated on.
+		 */
+		return apply_filters( 'bp_get_the_members_invitation_property_' . $property, $value );
+	}
+
+/**
+ * Output the action links for the current invitation.
+ *
+ * @since 8.0.0
+ *
+ * @param array|string $args Array of arguments.
+ */
+function bp_the_members_invitation_action_links( $args = '' ) {
+	echo bp_get_the_members_invitation_action_links( $args );
+}
+	/**
+	 * Return the action links for the current invitation.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param array|string $args {
+	 *     @type string $before  HTML before the links.
+	 *     @type string $after   HTML after the links.
+	 *     @type string $sep     HTML between the links.
+	 *     @type array  $links   Array of links to implode by 'sep'.
+	 *     @type int    $user_id User ID to fetch action links for. Defaults to displayed user ID.
+	 * }
+	 * @return string HTML links for actions to take on single notifications.
+	 */
+	function bp_get_the_members_invitation_action_links( $args = '' ) {
+		// Set default user ID to use.
+		$inviter_id = isset( $args['inviter_id'] ) ? $args['inviter_id'] : bp_displayed_user_id();
+
+		// Parse.
+		$r = wp_parse_args( $args, array(
+			'before' => '',
+			'after'  => '',
+			'sep'    => ' | ',
+			'links'  => array(
+				bp_get_the_members_invitation_resend_link( $inviter_id ),
+				bp_get_the_members_invitation_delete_link( $inviter_id )
+			)
+		) );
+
+		// Build the links.
+		$retval = $r['before'] . implode( $r['sep'], $r['links'] ) . $r['after'];
+
+		/**
+		 * Filters the action links for the current invitation.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param string $retval HTML links for actions to take on single invitation.
+		 * @param array  $r      Array of parsed arguments.
+		 */
+		return apply_filters( 'bp_get_the_members_invitation_action_links', $retval, $r );
+	}
+
+/**
+ * Output the resend link for the current invitation.
+ *
+ * @since 8.0.0
+ *
+ * @param int $user_id The user ID.
+ */
+function bp_the_members_invitations_resend_link( $user_id = 0 ) {
+	echo bp_get_the_members_invitation_delete_link( $user_id );
+}
+	/**
+	 * Return the resend link for the current notification.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param int $user_id The user ID.
+	 * @return string
+	 */
+	function bp_get_the_members_invitation_resend_link( $user_id = 0 ) {
+		// Set default user ID to use.
+		$user_id = 0 === $user_id ? bp_displayed_user_id() : $user_id;
+
+		// Don't allow resending of accepted invitations.
+		if ( bp_get_the_members_invitation_property( 'accepted' ) ) {
+			return;
+		}
+
+		$retval = sprintf( '<a href="%1$s" class="resend secondary confirm bp-tooltip">%2$s</a>', esc_url( bp_get_the_members_invitations_resend_url( $user_id ) ), __( 'Resend', 'buddypress' ) );
+
+		/**
+		 * Filters the resend link for the current invitation.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param string $retval  HTML for the delete link for the current notification.
+		 * @param int    $user_id The user ID.
+		 */
+		return apply_filters( 'bp_get_the_members_invitation_resend_link', $retval, $user_id );
+	}
+
+/**
+ * Output the URL used for resending a single invitation.
+ *
+ * Since this function directly outputs a URL, it is escaped.
+ *
+ * @since 8.0.0
+ *
+ * @param int $user_id The user ID.
+ */
+function bp_the_members_invitations_resend_url( $user_id = 0 ) {
+	echo esc_url( bp_get_the_members_invitations_resend_url( $user_id ) );
+}
+	/**
+	 * Return the URL used for resending a single invitation.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param int $user_id The user ID.
+	 * @return string
+	 */
+	function bp_get_the_members_invitations_resend_url( $user_id = 0 ) {
+		// Set default user ID to use.
+		$user_id = 0 === $user_id ? bp_displayed_user_id() : $user_id;
+		$link = bp_get_members_invitations_list_invites_permalink( $user_id );
+
+		// Get the ID.
+		$id = bp_get_the_members_invitation_property( 'id' );
+
+		// Get the args to add to the URL.
+		$args = array(
+			'action'        => 'resend',
+			'invitation_id' => $id
+		);
+
+		// Add the args.
+		$url = add_query_arg( $args, $link );
+
+		// Add the nonce.
+		$url = wp_nonce_url( $url, 'bp_network_invitation_resend_' . $id );
+
+		/**
+		 * Filters the URL used for resending a single invitation.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param string $url     URL used for deleting a single invitation.
+		 * @param int    $user_id The user ID.
+		 */
+		return apply_filters( 'bp_get_the_members_invitations_resend_url', $url, $user_id );
+	}
+
+/**
+ * Output the delete link for the current invitation.
+ *
+ * @since 8.0.0
+ *
+ * @param int $user_id The user ID.
+ */
+function bp_the_members_invitations_delete_link( $user_id = 0 ) {
+	echo bp_get_the_members_invitation_delete_link( $user_id );
+}
+	/**
+	 * Return the delete link for the current invitation.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param int $user_id The user ID.
+	 * @return string
+	 */
+	function bp_get_the_members_invitation_delete_link( $user_id = 0 ) {
+		// Set default user ID to use.
+		$user_id = 0 === $user_id ? bp_displayed_user_id() : $user_id;
+
+		// Modify the message for accepted/not accepted invitatons.
+		if ( bp_get_the_members_invitation_property( 'accepted' ) ) {
+			$message = __( 'Delete', 'buddypress' );
+		} else {
+			$message = __( 'Cancel', 'buddypress' );
+		}
+
+		$retval = sprintf(
+			'<a href="%1$s" class="delete secondary confirm bp-tooltip">%2$s</a>',
+			esc_url( bp_get_the_members_invitations_delete_url( $user_id ) ),
+			esc_html( $message )
+		);
+
+		/**
+		 * Filters the delete link for the current invitation.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param string $retval  HTML for the delete link for the current notification.
+		 * @param int    $user_id The user ID.
+		 */
+		return apply_filters( 'bp_get_the_members_invitation_delete_link', $retval, $user_id );
+	}
+
+/**
+ * Output the URL used for deleting a single invitation.
+ *
+ * Since this function directly outputs a URL, it is escaped.
+ *
+ * @since 8.0.0
+ *
+ * @param int $user_id The user ID.
+ */
+function bp_the_members_invitations_delete_url( $user_id = 0 ) {
+	echo esc_url( bp_get_the_members_invitations_delete_url( $user_id ) );
+}
+	/**
+	 * Return the URL used for deleting a single invitation.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param int $user_id The user ID.
+	 * @return string
+	 */
+	function bp_get_the_members_invitations_delete_url( $user_id = 0 ) {
+		// Set default user ID to use.
+		$user_id = 0 === $user_id ? bp_displayed_user_id() : $user_id;
+		$link = bp_get_members_invitations_list_invites_permalink( $user_id );
+
+		// Get the ID.
+		$id = bp_get_the_members_invitation_property( 'id' );
+
+		// Get the args to add to the URL.
+		$args = array(
+			'action'        => 'cancel',
+			'invitation_id' => $id
+		);
+
+		// Add the args.
+		$url = add_query_arg( $args, $link );
+
+		// Add the nonce.
+		$url = wp_nonce_url( $url, 'bp_members_invitations_cancel_' . $id );
+
+		/**
+		 * Filters the URL used for deleting a single invitation.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param string $url     URL used for deleting a single invitation.
+		 * @param int    $user_id The user ID.
+		 */
+		return apply_filters( 'bp_get_the_members_invitations_delete_url', $url, $user_id );
+	}
+
+/**
+ * Output the members invitations list permalink for a user.
+ *
+ * @since 8.0.0
+ *
+ * @param int $user_id The user ID.
+ */
+function bp_members_invitations_list_invites_permalink( $user_id = 0 ) {
+	echo bp_get_members_invitations_list_invites_permalink( $user_id );
+}
+	/**
+	 * Return the members invitations list permalink for a user.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @return string Members invitations list permalink for a user.
+	 */
+	function bp_get_members_invitations_list_invites_permalink( $user_id = 0 ) {
+		if ( 0 === $user_id ) {
+			$user_id = bp_loggedin_user_id();
+			$domain  = bp_loggedin_user_domain();
+		} else {
+			$domain = bp_core_get_user_domain( (int) $user_id );
+		}
+
+		$retval = trailingslashit( $domain . bp_get_members_invitations_slug() . '/list-invites' );
+
+		/**
+		 * Filters the members invitations list permalink for a user.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param string $retval  Permalink for the sent invitation list screen.
+		 * @param int    $user_id The user ID.
+		 */
+		return apply_filters( 'bp_get_members_invitations_list_invites_permalink', $retval, $user_id );
+	}
+
+/**
+ * Output the send invitation permalink for a user.
+ *
+ * @since 8.0.0
+ *
+ * @param int $user_id The user ID.
+ */
+function bp_members_invitations_send_invites_permalink( $user_id = 0 ) {
+	echo bp_get_members_invitations_send_invites_permalink( $user_id );
+}
+	/**
+	 * Return the send invitations permalink.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param int $user_id The user ID.
+	 * @return string      The send invitations permalink.
+	 */
+	function bp_get_members_invitations_send_invites_permalink( $user_id = 0 ) {
+		if ( 0 === $user_id ) {
+			$user_id = bp_loggedin_user_id();
+			$domain  = bp_loggedin_user_domain();
+		} else {
+			$domain = bp_core_get_user_domain( (int) $user_id );
+		}
+
+		$retval = trailingslashit( $domain . bp_get_members_invitations_slug() . '/send-invites' );
+
+		/**
+		 * Filters the send invitations permalink.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param string $retval  Permalink for the sent invitation list screen.
+		 * @param int    $user_id The user ID.
+		 */
+		return apply_filters( 'bp_get_members_invitations_send_invites_permalink', $retval, $user_id );
+	}
diff --git src/bp-members/classes/class-bp-members-admin.php src/bp-members/classes/class-bp-members-admin.php
index 64903c107..8c1d68b46 100644
--- src/bp-members/classes/class-bp-members-admin.php
+++ src/bp-members/classes/class-bp-members-admin.php
@@ -140,6 +140,8 @@ class BP_Members_Admin {
 		$this->users_url    = bp_get_admin_url( 'users.php' );
 		$this->users_screen = bp_core_do_network_admin() ? 'users-network' : 'users';
 
+		$this->members_invites_page = '';
+
 		// Specific config: BuddyPress is not network activated.
 		$this->subsite_activated = (bool) is_multisite() && ! bp_is_network_activated();
 
@@ -219,6 +221,13 @@ class BP_Members_Admin {
 			// Registration is turned on.
 			add_action( 'update_site_option_registration',  array( $this, 'multisite_registration_on' ),   10, 2 );
 			add_action( 'update_option_users_can_register', array( $this, 'single_site_registration_on' ), 10, 2 );
+
+			// Member invitations are enabled.
+			if ( bp_is_network_activated() ) {
+				add_action( 'update_site_option_bp-enable-members-invitations', array( $this, 'multisite_registration_on' ), 10, 2 );
+			} else {
+				add_action( 'update_option_bp-enable-members-invitations', array( $this, 'single_site_registration_on' ), 10, 2 );
+			}
 		}
 
 		/** Users List - Members Types ***************************************
@@ -248,7 +257,9 @@ class BP_Members_Admin {
 	 * @param string $value
 	 */
 	public function multisite_registration_on( $option_name, $value ) {
-		if ( 'user' === $value || 'all' === $value ) {
+		// Is registration enabled or are network invitations enabled?
+		if ( ( 'user' === $value || 'all' === $value )
+			|| bp_get_members_invitations_allowed() ) {
 			bp_core_add_page_mappings( array(
 				'register' => 1,
 				'activate' => 1
@@ -266,7 +277,7 @@ class BP_Members_Admin {
 	 */
 	public function single_site_registration_on( $old_value, $value ) {
 		// Single site.
-		if ( ! is_multisite() && ! empty( $value ) ) {
+		if ( ! is_multisite() && ( ! empty( $value ) || bp_get_members_invitations_allowed() ) ) {
 			bp_core_add_page_mappings( array(
 				'register' => 1,
 				'activate' => 1
@@ -490,6 +501,23 @@ class BP_Members_Admin {
 			);
 		}
 
+		// 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';
+		} else {
+			$tools_parent = 'tools.php';
+		}
+
+		$hooks['members_invitations'] = $this->members_invites_page = add_submenu_page(
+			$tools_parent,
+			__( 'Manage Invitations',  'buddypress' ),
+			__( 'Manage Invitations',  'buddypress' ),
+			$this->capability,
+			'bp-members-invitations',
+			array( $this, 'invitations_admin' )
+		);
+
 		$edit_page         = 'user-edit';
 		$profile_page      = 'profile';
 		$this->users_page  = 'users';
@@ -510,7 +538,7 @@ class BP_Members_Admin {
 			$this->users_page   .= '-network';
 			$this->signups_page .= '-network';
 
-			$this->members_optouts_page .= '-network';
+			$this->members_invites_page .= '-network';
 		}
 
 		// Setup the screen ID's.
@@ -529,6 +557,9 @@ class BP_Members_Admin {
 		foreach ( $page_head as $head ) {
 			add_action( "admin_head-{$head}", array( $this, 'profile_admin_head' ) );
 		}
+
+		// Highlight the BuddyPress tools submenu when managing invitations.
+		add_action( "admin_head-{$this->members_invites_page}", 'bp_core_modify_admin_menu_highlight' );
 	}
 
 	/**
@@ -598,6 +629,13 @@ class BP_Members_Admin {
 	public function admin_head() {
 		remove_submenu_page( 'users.php',   'bp-profile-edit' );
 		remove_submenu_page( 'profile.php', 'bp-profile-edit' );
+
+		// Manage Invitations Tool screen is a tab of BP Tools.
+		if ( is_network_admin() ) {
+			remove_submenu_page( 'network-tools', 'bp-members-invitations' );
+		} else {
+			remove_submenu_page( 'tools.php', 'bp-members-invitations' );
+		}
 	}
 
 	/** Community Profile *****************************************************/
@@ -1905,14 +1943,16 @@ class BP_Members_Admin {
 					}
 
 					if ( ! empty( $_REQUEST['notdeleted'] ) ) {
+						$notdeleted         = absint( $_REQUEST['notdeleted'] );
 						$notice['message'] .= sprintf(
-							/* translators: %s: number of deleted signups not deleted */
-							_nx( '%s sign-up was not deleted.', '%s sign-ups were not deleted.',
-							 absint( $_REQUEST['notdeleted'] ),
-							 'signup notdeleted',
-							 'buddypress'
+							_nx(
+								/* translators: %s: number of deleted signups not deleted */
+								'%s sign-up was not deleted.', '%s sign-ups were not deleted.',
+								$notdeleted,
+								'signup notdeleted',
+								'buddypress'
 							),
-							number_format_i18n( absint( $_REQUEST['notdeleted'] ) )
+							number_format_i18n( $notdeleted )
 						);
 
 						if ( empty( $_REQUEST['deleted'] ) ) {
@@ -2566,5 +2606,570 @@ class BP_Members_Admin {
 
 		return $value;
 	}
+
+	/**
+	 * Set up the signups admin page.
+	 *
+	 * Loaded before the page is rendered, this function does all initial
+	 * setup, including: processing form requests, registering contextual
+	 * help, and setting up screen options.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @global $bp_members_invitations_list_table
+	 */
+	public function members_invitations_admin_load() {
+		global $bp_members_invitations_list_table;
+
+		// Build redirection URL.
+		$redirect_to = remove_query_arg( array( 'action', 'error', 'updated', 'activated', 'notactivated', 'deleted', 'notdeleted', 'resent', 'notresent', 'do_delete', 'do_resend', 'do_activate', '_wpnonce', 'signup_ids' ), $_SERVER['REQUEST_URI'] );
+		$doaction    = bp_admin_list_table_current_bulk_action();
+
+		/**
+		 * Fires at the start of the member invitations admin load.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param string $doaction Current bulk action being processed.
+		 * @param array  $_REQUEST Current $_REQUEST global.
+		 */
+		do_action( 'bp_members_invitations_admin_load', $doaction, $_REQUEST );
+
+		/**
+		 * Filters the allowed actions for use in the user signups admin page.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param array $value Array of allowed actions to use.
+		 */
+		$allowed_actions = apply_filters( 'bp_members_invitations_admin_allowed_actions', array( 'do_delete',  'do_resend' ) );
+
+		// Prepare the display of the bulk invitation action screen.
+		if ( ! in_array( $doaction, $allowed_actions ) ) {
+
+			$bp_members_invitations_list_table = self::get_list_table_class( 'BP_Members_Invitations_List_Table', 'users' );
+
+			// The per_page screen option.
+			add_screen_option( 'per_page', array( 'label' => _x( 'Members Invitations', 'Members Invitations per page (screen options)', 'buddypress' ) ) );
+
+			get_current_screen()->add_help_tab( array(
+				'id'      => 'bp-members-invitations-overview',
+				'title'   => __( 'Overview', 'buddypress' ),
+				'content' =>
+				'<p>' . __( 'This is the administration screen for member invitations on your site.', 'buddypress' ) . '</p>' .
+				'<p>' . __( 'From the screen options, you can customize the displayed columns and the pagination of this screen.', 'buddypress' ) . '</p>' .
+				'<p>' . __( 'You can reorder the list of invitations by clicking on the Invitee, Inviter, Date Modified, Email Sent, or Accepted column headers.', 'buddypress' ) . '</p>' .
+				'<p>' . __( 'Using the search form, you can find specific invitations more easily. The Invitee Email field will be included in the search.', 'buddypress' ) . '</p>'
+			) );
+
+			get_current_screen()->add_help_tab( array(
+				'id'      => 'bp-members-invitations-actions',
+				'title'   => __( 'Actions', 'buddypress' ),
+				'content' =>
+				'<p>' . __( 'Hovering over a row in the pending accounts list will display action links that allow you to manage pending accounts. You can perform the following actions:', 'buddypress' ) . '</p>' .
+				'<ul><li>' . __( '"Send" or "Resend" takes you to the confirmation screen before being able to send or resend the invitation email to the desired pending invitee.', 'buddypress' ) . '</li>' .
+				'<li>' . __( '"Delete" allows you to delete an unsent or accepted invitation from your site; "Cancel" allows you to cancel a sent, but not yet accepted, invitation. You will be asked to confirm this deletion.', 'buddypress' ) . '</li></ul>' .
+				'<p>' . __( 'Bulk actions allow you to perform these actions for the selected rows.', 'buddypress' ) . '</p>'
+			) );
+
+			// Help panel - sidebar links.
+			get_current_screen()->set_help_sidebar(
+				'<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
+				'<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
+			);
+
+			// Add accessible hidden headings and text for the Pending Users screen.
+			get_current_screen()->set_screen_reader_content( array(
+				/* translators: accessibility text */
+				'heading_views'      => __( 'Filter invitations list', 'buddypress' ),
+				/* translators: accessibility text */
+				'heading_pagination' => __( 'Invitation list navigation', 'buddypress' ),
+				/* translators: accessibility text */
+				'heading_list'       => __( 'Invitations list', 'buddypress' ),
+			) );
+
+		} else {
+			if ( empty( $_REQUEST['invite_ids' ] ) ) {
+				return;
+			}
+			$invite_ids = wp_parse_id_list( $_REQUEST['invite_ids' ] );
+
+			// Handle resent invitations.
+			if ( 'do_resend' == $doaction ) {
+
+				// Nonce check.
+				check_admin_referer( 'invitations_resend' );
+
+				$success = 0;
+				foreach ( $invite_ids as $invite_id ) {
+					if ( bp_members_invitation_resend_by_id( $invite_id ) ) {
+						$success++;
+					}
+				}
+
+				$query_arg = array( 'updated' => 'resent' );
+
+				if ( ! empty( $success ) ) {
+					$query_arg['resent'] = $success;
+				}
+
+				$not_sent = count( $invite_ids ) - $success;
+				if ( $not_sent > 0 ) {
+					$query_arg['notsent'] = $not_sent;
+				}
+
+				$redirect_to = add_query_arg( $query_arg, $redirect_to );
+
+				bp_core_redirect( $redirect_to );
+
+			// Handle invitation deletion.
+			} elseif ( 'do_delete' == $doaction ) {
+
+				// Nonce check.
+				check_admin_referer( 'invitations_delete' );
+
+				$success = 0;
+				foreach ( $invite_ids as $invite_id ) {
+					if ( bp_members_invitations_delete_by_id( $invite_id ) ) {
+						$success++;
+					}
+				}
+
+				$query_arg = array( 'updated' => 'deleted' );
+
+				if ( ! empty( $success ) ) {
+					$query_arg['deleted'] = $success;
+				}
+
+				$notdeleted = count( $invite_ids ) - $success;
+				if ( $notdeleted > 0 ) {
+					$query_arg['notdeleted'] = $notdeleted;
+				}
+
+				$redirect_to = add_query_arg( $query_arg, $redirect_to );
+
+				bp_core_redirect( $redirect_to );
+
+			// Plugins can update other stuff from here.
+			} else {
+				$this->redirect = $redirect_to;
+
+				/**
+				 * Fires at end of member invitations admin load
+				 * if doaction does not match any actions.
+				 *
+				 * @since 8.0.0
+				 *
+				 * @param string $doaction Current bulk action being processed.
+				 * @param array  $_REQUEST Current $_REQUEST global.
+				 * @param string $redirect Determined redirect url to send user to.
+				 */
+				do_action( 'bp_members_admin_update_invitations', $doaction, $_REQUEST, $this->redirect );
+
+				bp_core_redirect( $this->redirect );
+			}
+		}
+	}
+
+	/**
+	 * Get admin notice when viewing the invitations management page.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @return array
+	 */
+	private function get_members_invitations_notice() {
+
+		// Setup empty notice for return value.
+		$notice = array();
+
+		// Updates.
+		if ( ! empty( $_REQUEST['updated'] ) ) {
+			switch ( $_REQUEST['updated'] ) {
+				case 'resent':
+					$notice = array(
+						'class'   => 'updated',
+						'message' => ''
+					);
+
+					if ( ! empty( $_REQUEST['resent'] ) ) {
+						$resent             = absint( $_REQUEST['resent'] );
+						$notice['message'] .= sprintf(
+							_nx(
+								/* translators: %s: number of invitation emails sent */
+								'%s invtitation email successfully sent! ', '%s invitation emails successfully sent! ',
+								$resent,
+								'members invitation resent',
+								'buddypress'
+							),
+							number_format_i18n( $resent )
+						);
+					}
+
+					if ( ! empty( $_REQUEST['notsent'] ) ) {
+						$notsent            = absint( $_REQUEST['notsent'] );
+						$notice['message'] .= sprintf(
+							_nx(
+								/* translators: %s: number of unsent invitation emails */
+								'%s invitation email was not sent.', '%s invitation emails were not sent.',
+								$notsent,
+								'members invitation notsent',
+								'buddypress'
+							),
+							number_format_i18n( $notsent )
+						);
+
+						if ( empty( $_REQUEST['resent'] ) ) {
+							$notice['class'] = 'error';
+						}
+					}
+
+					break;
+
+				case 'deleted':
+					$notice = array(
+						'class'   => 'updated',
+						'message' => ''
+					);
+
+					if ( ! empty( $_REQUEST['deleted'] ) ) {
+						$deleted            = absint( $_REQUEST['deleted'] );
+						$notice['message'] .= sprintf(
+							_nx(
+								/* translators: %s: number of deleted invitations */
+								'%s invitation successfully deleted!', '%s invitations successfully deleted!',
+								$deleted,
+								'members invitation deleted',
+								'buddypress'
+							),
+							number_format_i18n( $deleted )
+						);
+					}
+
+					if ( ! empty( $_REQUEST['notdeleted'] ) ) {
+						$notdeleted         = absint( $_REQUEST['notdeleted'] );
+						$notice['message'] .= sprintf(
+							_nx(
+								/* translators: %s: number of invitations that failed to be deleted */
+								'%s invitation was not deleted.', '%s invitations were not deleted.',
+								$notdeleted,
+								'members invitation notdeleted',
+								'buddypress'
+							),
+							number_format_i18n( $notdeleted )
+						);
+
+						if ( empty( $_REQUEST['deleted'] ) ) {
+							$notice['class'] = 'error';
+						}
+					}
+
+					break;
+			}
+		}
+
+		// Errors.
+		if ( ! empty( $_REQUEST['error'] ) ) {
+			switch ( $_REQUEST['error'] ) {
+				case 'do_resend':
+					$notice = array(
+						'class'   => 'error',
+						'message' => esc_html__( 'There was a problem sending the invitation emails. Please try again.', 'buddypress' ),
+					);
+					break;
+
+				case 'do_delete':
+					$notice = array(
+						'class'   => 'error',
+						'message' => esc_html__( 'There was a problem deleting invitations. Please try again.', 'buddypress' ),
+					);
+					break;
+			}
+		}
+
+		return $notice;
+	}
+
+	/**
+	 * Member invitations admin page router.
+	 *
+	 * Depending on the context, display
+	 * - the list of invitations,
+	 * - or the delete confirmation screen,
+	 * - or the "resend" email confirmation screen.
+	 *
+	 * Also prepare the admin notices.
+	 *
+	 * @since 8.0.0
+	 */
+	public function invitations_admin() {
+		$doaction = bp_admin_list_table_current_bulk_action();
+
+		// Prepare notices for admin.
+		$notice = $this->get_members_invitations_notice();
+
+		// Display notices.
+		if ( ! empty( $notice ) ) :
+			if ( 'updated' === $notice['class'] ) : ?>
+
+				<div id="message" class="<?php echo esc_attr( $notice['class'] ); ?> notice is-dismissible">
+
+			<?php else: ?>
+
+				<div class="<?php echo esc_attr( $notice['class'] ); ?> notice is-dismissible">
+
+			<?php endif; ?>
+
+				<p><?php echo $notice['message']; ?></p>
+			</div>
+
+		<?php endif;
+
+		// Show the proper screen.
+		switch ( $doaction ) {
+			case 'delete' :
+			case 'resend' :
+				$this->invitations_admin_manage( $doaction );
+				break;
+
+			default:
+				$this->invitations_admin_index();
+				break;
+		}
+	}
+
+	/**
+	 * This is the list of invitations.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @global $plugin_page
+	 * @global $bp_members_invitations_list_table
+	 */
+	public function invitations_admin_index() {
+		global $plugin_page, $bp_members_invitations_list_table;
+
+		$usersearch = ! empty( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : '';
+
+		// Prepare the group items for display.
+		$bp_members_invitations_list_table->prepare_items();
+
+		if ( is_network_admin() ) {
+			$form_url = network_admin_url( 'admin.php' );
+		} else {
+			$form_url = bp_get_admin_url( 'tools.php' );
+		}
+
+		$form_url = add_query_arg(
+			array(
+				'page' => 'bp-members-invitations',
+			),
+			$form_url
+		);
+
+		$search_form_url = remove_query_arg(
+			array(
+				'action',
+				'deleted',
+				'notdeleted',
+				'error',
+				'updated',
+				'delete',
+				'activate',
+				'activated',
+				'notactivated',
+				'resend',
+				'resent',
+				'notresent',
+				'do_delete',
+				'do_activate',
+				'do_resend',
+				'action2',
+				'_wpnonce',
+				'invite_ids'
+			), $_SERVER['REQUEST_URI']
+		);
+
+		?>
+
+		<div class="wrap">
+			<h1 class="wp-heading-inline"><?php esc_html_e( 'BuddyPress tools', 'buddypress' ); ?></h1>
+			<hr class="wp-header-end">
+
+			<h2 class="nav-tab-wrapper"><?php bp_core_admin_tabs( __( 'Manage Invitations', 'buddypress' ), 'tools' ); ?></h2>
+
+			<?php
+			if ( $usersearch ) {
+				printf( '<span class="subtitle">' . __( 'Search results for &#8220;%s&#8221;', 'buddypress' ) . '</span>', esc_html( $usersearch ) );
+			}
+			?>
+
+			<hr class="wp-header-end">
+
+			<?php // Display each invitation on its own row. ?>
+			<?php $bp_members_invitations_list_table->views(); ?>
+
+			<form id="bp-members-invitations-search-form" action="<?php echo esc_url( $search_form_url ) ;?>">
+				<input type="hidden" name="page" value="<?php echo esc_attr( $plugin_page ); ?>" />
+				<?php $bp_members_invitations_list_table->search_box( __( 'Search Invitations', 'buddypress' ), 'bp-members-invitations' ); ?>
+			</form>
+
+			<form id="bp-members-invitations-form" action="<?php echo esc_url( $form_url );?>" method="post">
+				<?php $bp_members_invitations_list_table->display(); ?>
+			</form>
+		</div>
+	<?php
+	}
+
+	/**
+	 * This is the confirmation screen for actions.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param string $action Delete or resend invitation.
+	 * @return null|false
+	 */
+	public function invitations_admin_manage( $action = '' ) {
+		if ( ! current_user_can( $this->capability ) || empty( $action ) ) {
+			die( '-1' );
+		}
+
+		// Get the IDs from the URL.
+		$ids = false;
+		if ( ! empty( $_POST['invite_ids'] ) ) {
+			$ids = wp_parse_id_list( $_POST['invite_ids'] );
+		} elseif ( ! empty( $_GET['invite_id'] ) ) {
+			$ids = absint( $_GET['invite_id'] );
+		}
+
+
+		if ( empty( $ids ) ) {
+			return false;
+		}
+
+		// Check invite IDs and set up strings.
+		switch ( $action ) {
+			case 'delete' :
+				// Query for matching invites, and filter out bad IDs.
+				$args = array(
+					'id'          => $ids,
+					'invite_sent' => 'all',
+					'accepted'    => 'all',
+				);
+				$invites    = bp_members_invitations_get_invites( $args );
+				$invite_ids = wp_list_pluck( $invites, 'id' );
+
+				$header_text = __( 'Delete Invitations', 'buddypress' );
+				if ( 0 === count( $invite_ids ) ) {
+					$helper_text = __( 'No invites were found, nothing to delete!', 'buddypress' );
+				} else {
+					$helper_text = _n( 'You are about to delete the following invitation:', 'You are about to delete the following invitations:', count( $invite_ids ), 'buddypress' );
+				}
+				break;
+
+			case 'resend' :
+				/**
+				 * Query for matching invites, and filter out bad IDs
+				 * or those that have already been accepted.
+				 */
+				$args = array(
+					'id'          => $ids,
+					'invite_sent' => 'all',
+					'accepted'    => 'pending',
+				);
+				$invites    = bp_members_invitations_get_invites( $args );
+				$invite_ids = wp_list_pluck( $invites, 'id' );
+
+				$header_text = __( 'Resend Invitation Emails', 'buddypress' );
+				if ( 0 === count( $invite_ids ) ) {
+					$helper_text = __( 'No pending invites were found, nothing to resend!', 'buddypress' );
+				} else {
+					$helper_text = _n( 'You are about to resend an invitation email to the following address:', 'You are about to resend invitation emails to the following addresses:', count( $invite_ids ), 'buddypress' );
+				}
+				break;
+		}
+
+		// These arguments are added to all URLs.
+		$url_args = array( 'page' => 'bp-members-invitations' );
+
+		// These arguments are only added when performing an action.
+		$action_args = array(
+			'action'     => 'do_' . $action,
+			'invite_ids' => implode( ',', $invite_ids )
+		);
+
+		if ( is_network_admin() ) {
+			$base_url = network_admin_url( 'admin.php' );
+		} else {
+			$base_url = bp_get_admin_url( 'tools.php' );
+		}
+
+		$cancel_url = add_query_arg( $url_args, $base_url );
+		$action_url = wp_nonce_url(
+			add_query_arg(
+				array_merge( $url_args, $action_args ),
+				$base_url
+			),
+			'invitations_' . $action
+		);
+
+		?>
+
+		<div class="wrap">
+			<h1 class="wp-heading-inline"><?php echo esc_html( $header_text ); ?></h1>
+			<hr class="wp-header-end">
+
+			<p><?php echo esc_html( $helper_text ); ?></p>
+
+			<?php if ( $invites ) : ?>
+
+				<ol class="bp-invitations-list">
+					<?php foreach ( $invites as $invite ) :
+						if ( $invite->invite_sent ) {
+							$last_notified = mysql2date( 'Y/m/d g:i:s a', $invite->date_modified );
+						} else {
+							$last_notified = __( 'Not yet notified', 'buddypress');
+						}
+						?>
+
+						<li>
+							<strong><?php echo esc_html( $invite->invitee_email ) ?></strong>
+
+							<?php if ( 'resend' === $action ) : ?>
+
+								<p class="description">
+									<?php
+									/* translators: %s: notification date */
+									printf( esc_html__( 'Last notified: %s', 'buddypress'), $last_notified );
+									?>
+								</p>
+
+							<?php endif; ?>
+
+						</li>
+
+					<?php endforeach; ?>
+				</ol>
+
+			<?php endif ; ?>
+
+			<?php if ( 'delete' === $action ) : ?>
+
+				<p><strong><?php esc_html_e( 'This action cannot be undone.', 'buddypress' ) ?></strong></p>
+
+			<?php endif; ?>
+
+			<?php if ( $invites ) : ?>
+
+				<a class="button-primary" href="<?php echo esc_url( $action_url ); ?>" <?php disabled( ! $invites ); ?>><?php esc_html_e( 'Confirm', 'buddypress' ); ?></a>
+
+			<?php endif; ?>
+
+			<a class="button" href="<?php echo esc_url( $cancel_url ); ?>"><?php esc_html_e( 'Cancel', 'buddypress' ) ?></a>
+		</div>
+
+		<?php
+	}
+
 }
 endif; // End class_exists check.
diff --git src/bp-members/classes/class-bp-members-component.php src/bp-members/classes/class-bp-members-component.php
index 4db47da8d..c819eb08b 100644
--- src/bp-members/classes/class-bp-members-component.php
+++ src/bp-members/classes/class-bp-members-component.php
@@ -39,7 +39,8 @@ class BP_Members_Component extends BP_Component {
 			buddypress()->plugin_dir,
 			array(
 				'adminbar_myaccount_order' => 20,
-				'search_query_arg' => 'members_search',
+				'search_query_arg'         => 'members_search',
+				'features'                 => array( 'invitations' )
 			)
 		);
 	}
@@ -64,6 +65,8 @@ class BP_Members_Component extends BP_Component {
 			'blocks',
 			'widgets',
 			'cache',
+			'invitations',
+			'notifications',
 		);
 
 		if ( bp_is_active( 'activity' ) ) {
@@ -137,6 +140,15 @@ class BP_Members_Component extends BP_Component {
 			// Theme compatibility.
 			new BP_Registration_Theme_Compat();
 		}
+
+		// Invitations.
+		if ( is_user_logged_in() && bp_is_user_members_invitations() ) {
+			if ( bp_is_user_members_invitations_list() ) {
+				require $this->path . 'bp-members/screens/list-invites.php';
+			} else {
+				require $this->path . 'bp-members/screens/send-invites.php';
+			}
+		}
 	}
 
 	/**
@@ -180,7 +192,8 @@ class BP_Members_Component extends BP_Component {
 				'table_name_last_activity' => bp_core_get_table_prefix() . 'bp_activity',
 				'table_name_optouts'       => bp_core_get_table_prefix() . 'bp_optouts',
 				'table_name_signups'       => $wpdb->base_prefix . 'signups', // Signups is a global WordPress table.
-			)
+			),
+			'notification_callback' => 'members_format_notifications',
 		);
 
 		parent::setup_globals( $args );
@@ -233,6 +246,11 @@ class BP_Members_Component extends BP_Component {
 			$bp->profile->slug = 'profile';
 			$bp->profile->id   = 'profile';
 		}
+
+		/** Network Invitations **************************************************
+		 */
+
+		$bp->members->invitations = new stdClass;
 	}
 
 	/**
@@ -468,7 +486,6 @@ class BP_Members_Component extends BP_Component {
 			}
 		}
 
-
 		parent::setup_nav( $main_nav, $sub_nav );
 	}
 
@@ -549,6 +566,25 @@ class BP_Members_Component extends BP_Component {
 		return $wp_admin_nav;
 	}
 
+	/**
+	 * Get the members invitations admin bar navs.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param  string $admin_bar_menu_id The Admin bar menu ID to attach sub items to.
+	 * @return array                     The members invitations admin navs.
+	 */
+	public function get_members_invitations_admin_navs( $admin_bar_menu_id = '' ) {
+		$wp_admin_nav = array();
+		$invite_link  = trailingslashit( bp_loggedin_user_domain() . bp_get_profile_slug() );
+
+		if ( ! $admin_bar_menu_id ) {
+			$admin_bar_menu_id = $this->id;
+		}
+
+		return $wp_admin_nav;
+	}
+
 	/**
 	 * Set up the Admin Bar.
 	 *
diff --git src/bp-members/classes/class-bp-members-invitation-manager.php src/bp-members/classes/class-bp-members-invitation-manager.php
new file mode 100644
index 000000000..061c5bade
--- /dev/null
+++ src/bp-members/classes/class-bp-members-invitation-manager.php
@@ -0,0 +1,176 @@
+<?php
+/**
+ * Membership invitations class.
+ *
+ * @package BuddyPress
+ * @subpackage Core
+ * @since 8.0.0
+ */
+
+// Exit if accessed directly.
+defined( 'ABSPATH' ) || exit;
+
+/**
+ * Membership invitations class.
+ *
+ * An extension of the core Invitations class that adapts the
+ * core logic to accommodate site membership invitation behavior.
+ *
+ * @since 8.0.0
+ */
+class BP_Members_Invitation_Manager extends BP_Invitation_Manager {
+	/**
+	 * Construct parameters.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param array|string $args.
+	 */
+	public function __construct( $args = '' ) {
+		parent::__construct();
+	}
+
+	/**
+	 * This is where custom actions are added to run when notifications of an
+	 * invitation or request need to be generated & sent.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param obj BP_Invitation $invitation The invitation to send.
+	 * @return bool True on success, false on failure.
+	 */
+	public function run_send_action( BP_Invitation $invitation ) {
+		// Notify site admins of the pending request
+		if ( 'request' === $invitation->type ) {
+			// Coming soon to a BuddyPress near you!
+			return true;
+		// Notify the invitee of the invitation.
+		} else {
+			// Stop if the invitation has already been accepted.
+			if ( $invitation->accepted ) {
+				return false;
+			}
+
+			$inviter_ud = bp_core_get_core_userdata( $invitation->inviter_id );
+
+			$invite_url = esc_url(
+				add_query_arg(
+					array(
+						'inv' => $invitation->id,
+						'ih'  => bp_members_invitations_get_hash( $invitation ),
+					),
+					bp_get_signup_page()
+				)
+			);
+			$unsubscribe_args = array(
+				'user_id'           => 0,
+				'email_address'     => $invitation->invitee_email,
+				'member_id'         => $invitation->inviter_id,
+				'notification_type' => 'bp-members-invitation',
+			);
+
+			$args = array(
+				'tokens' => array(
+					'inviter.name'      => bp_core_get_userlink( $invitation->inviter_id, true, false, true ),
+					'inviter.url'       => bp_core_get_user_domain( $invitation->inviter_id ),
+					'inviter.id'        => $invitation->inviter_id,
+					'invite.accept_url' => esc_url( $invite_url ),
+					'usermessage'       => wp_kses( $invitation->content, array() ),
+					'unsubscribe'       => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ),
+				),
+			);
+
+			return bp_send_email( 'bp-members-invitation', $invitation->invitee_email, $args );
+		}
+	}
+
+	/**
+	 * This is where custom actions are added to run when an invitation
+	 * or request is accepted.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param string $type Are we accepting an invitation or request?
+	 * @param array  $r    Parameters that describe the invitation being accepted.
+	 * @return bool True on success, false on failure.
+	 */
+	public function run_acceptance_action( $type, $r ) {
+		if ( ! $type || ! in_array( $type, array( 'request', 'invite' ), true ) ) {
+			return false;
+		}
+
+		if ( 'invite' === $type ) {
+
+			$invites = $this->get_invitations( $r );
+			if ( ! $invites ) {
+				return;
+			}
+
+			foreach ( $invites as $invite ) {
+				// Add the accepted invitation ID to the user's meta.
+				$new_user = get_user_by( 'email', $invite->invitee_email );
+				bp_update_user_meta( $new_user->ID, 'accepted_members_invitation', $invite->id );
+
+				// We will mark all invitations to this user as "accepted."
+				$args  = array(
+					'invitee_email' => $invite->invitee_email,
+					'item_id'       => get_current_network_id(),
+					'type'          => 'all'
+				);
+				$this->mark_accepted( $args );
+
+				/**
+				 * Fires after a user has accepted a site membership invite.
+				 *
+				 * @since 8.0.0
+				 *
+				 * @param BP_Invitation $invite    Invitation that was accepted.
+				 * @param WP_user       $new_user   ID of the user who accepted the membership invite.
+				 * @param int           $inviter_id ID of the user who invited this user to the site.
+				 */
+				do_action( 'community_membership_invite_accepted', $invite, $new_user, $invite->inviter_id );
+			}
+		}
+
+		return true;
+	}
+
+	/**
+	 * Should this invitation be created?
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param array $args.
+	 * @return bool
+	 */
+	public function allow_invitation( $args ) {
+		// Does the inviter have this capability?
+		if ( ! bp_user_can( $args['inviter_id'], 'bp_members_send_invitation' ) ) {
+			return false;
+		}
+
+		// Is the invited user eligible to receive an invitation? Hasn't opted out?
+		if ( ! bp_user_can( 0, 'bp_members_receive_invitation', $args ) ) {
+			return false;
+		}
+
+		return true;
+	}
+
+	/**
+	 * Should this request be created?
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param array $args.
+	 * @return bool.
+	 */
+	public function allow_request( $args ) {
+		// Does the requester have this capability?
+		if ( ! bp_user_can( 0, 'bp_network_request_membership', $args ) ) {
+			return false;
+		}
+
+		return true;
+	}
+}
diff --git src/bp-members/classes/class-bp-members-invitations-list-table.php src/bp-members/classes/class-bp-members-invitations-list-table.php
new file mode 100644
index 000000000..db5468ee4
--- /dev/null
+++ src/bp-members/classes/class-bp-members-invitations-list-table.php
@@ -0,0 +1,488 @@
+<?php
+/**
+ * BuddyPress Membership Invitation List Table class.
+ *
+ * @package BuddyPress
+ * @subpackage MembersAdminClasses
+ * @since 8.0.0
+ */
+
+// Exit if accessed directly.
+defined( 'ABSPATH' ) || exit;
+
+/**
+ * List table class for Invitations admin page.
+ *
+ * @since 8.0.0
+ */
+class BP_Members_Invitations_List_Table extends WP_Users_List_Table {
+
+	/**
+	 * The type of view currently being displayed.
+	 *
+	 * E.g. "All", "Pending", "Sent", "Unsent"...
+	 *
+	 * @since 8.0.0
+	 * @var string
+	 */
+	public $active_filters = array();
+
+	/**
+	 * Invitation counts.
+	 *
+	 * @since 8.0.0
+	 * @var int
+	 */
+	public $total_items = 0;
+
+	/**
+	 * Constructor.
+	 *
+	 * @since 8.0.0
+	 */
+	public function __construct() {
+		// Define singular and plural labels, as well as whether we support AJAX.
+		parent::__construct( array(
+			'ajax'     => false,
+			'plural'   => 'invitations',
+			'singular' => 'invitation',
+			'screen'   => get_current_screen()->id,
+		) );
+	}
+
+	/**
+	 * Set up items for display in the list table.
+	 *
+	 * Handles filtering of data, sorting, pagination, and any other data
+	 * manipulation required prior to rendering.
+	 *
+	 * @since 8.0.0
+	 */
+	public function prepare_items() {
+		global $usersearch;
+
+		$search   = isset( $_REQUEST['s'] ) ? $_REQUEST['s'] : '';
+		$per_page = $this->get_items_per_page( str_replace( '-', '_', "{$this->screen->id}_per_page" ) );
+		$paged    = $this->get_pagenum();
+
+		$args = array(
+			'invite_sent'       => 'all',
+			'accepted'          => 'all',
+			'search_terms'      => $search,
+			'order_by'          => 'date_modified',
+			'sort_order'        => 'DESC',
+			'page'              => $paged,
+			'per_page'          => $per_page,
+		);
+
+		if ( isset( $_REQUEST['accepted'] ) && in_array( $_REQUEST['accepted'], array( 'pending', 'accepted' ), true ) ) {
+			$args['accepted']       = $_REQUEST['accepted'];
+			$this->active_filters[] = $_REQUEST['accepted'];
+		}
+		if ( isset( $_REQUEST['sent'] ) && in_array( $_REQUEST['sent'], array( 'draft', 'sent' ), true ) ) {
+			$args['invite_sent']    = $_REQUEST['sent'];
+			$this->active_filters[] = $_REQUEST['sent'];
+		}
+
+		if ( isset( $_REQUEST['orderby'] ) ) {
+			$args['order_by'] = $_REQUEST['orderby'];
+		}
+
+		if ( isset( $_REQUEST['order'] ) ) {
+			$args['sort_order'] = $_REQUEST['order'];
+		}
+
+		$invites_class     = new BP_Members_Invitation_Manager();
+		$this->items       = $invites_class->get_invitations( $args );
+		$this->total_items = $invites_class->get_invitations_total_count( $args );
+
+		$this->set_pagination_args( array(
+			'total_items' => $this->total_items,
+			'per_page'    => $per_page,
+		) );
+	}
+
+	/**
+	 * Get the list of views available on this table (e.g. "all", "public").
+	 *
+	 * @since 8.0.0
+	 */
+	public function views() {
+		$tools_url = bp_get_admin_url( 'tools.php' );
+
+		if ( is_network_admin() ) {
+			$tools_url = network_admin_url( 'admin.php' );
+		}
+
+		$url_base = add_query_arg(
+			array(
+				'page' => 'bp-members-invitations',
+			),
+			$tools_url
+		);
+		?>
+
+		<h2 class="screen-reader-text"><?php
+			/* translators: accessibility text */
+			esc_html_e( 'Filter invitations list', 'buddypress' );
+		?></h2>
+		<ul class="subsubsub">
+			<li class="all">
+				<a href="<?php echo esc_url( $url_base ); ?>" class="<?php if ( empty( $this->active_filters ) ) echo 'current'; ?>">
+					<?php esc_html_e( 'All', 'buddypress' ); ?>
+				</a> |
+			</li>
+			<li class="pending">
+				<a href="<?php echo esc_url( add_query_arg( 'accepted', 'pending', $url_base ) ); ?>" class="<?php if ( in_array( 'pending', $this->active_filters, true ) ) echo 'current'; ?>">
+					<?php esc_html_e( 'Pending', 'buddypress' ); ?>
+				</a> |
+			</li>
+			<li class="accepted">
+				<a href="<?php echo esc_url( add_query_arg( 'accepted', 'accepted', $url_base ) ); ?>" class="<?php if ( in_array( 'accepted', $this->active_filters, true ) ) echo 'current'; ?>">
+					<?php esc_html_e( 'Accepted', 'buddypress' ); ?>
+				</a> |
+			</li>
+			<li class="draft">
+				<a href="<?php echo esc_url( add_query_arg( 'sent', 'draft', $url_base ) ); ?>" class="<?php if ( in_array( 'draft', $this->active_filters, true ) ) echo 'current'; ?>">
+					<?php esc_html_e( 'Draft (Unsent)', 'buddypress' ); ?>
+				</a> |
+			</li>
+			<li class="sent">
+				<a href="<?php echo esc_url( add_query_arg( 'sent', 'sent', $url_base ) ); ?>" class="<?php if ( in_array( 'sent', $this->active_filters, true ) ) echo 'current'; ?>">
+					<?php esc_html_e( 'Sent', 'buddypress' ); ?>
+				</a>
+			</li>
+
+			<?php
+
+			/**
+			 * Fires inside listing of views so plugins can add their own.
+			 *
+			 * @since 8.0.0
+			 *
+			 * @param string $url_base       Current URL base for view.
+			 * @param array  $active_filters Current filters being requested.
+			 */
+			do_action( 'bp_members_invitations_list_table_get_views', $url_base, $this->active_filters ); ?>
+		</ul>
+	<?php
+	}
+
+	/**
+	 * Get rid of the extra nav.
+	 *
+	 * WP_Users_List_Table will add an extra nav to change user's role.
+	 * As we're dealing with invitations, we don't need this.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param array $which Current table nav item.
+	 */
+	public function extra_tablenav( $which ) {
+		return;
+	}
+
+	/**
+	 * Specific signups columns.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @return array
+	 */
+	public function get_columns() {
+
+		/**
+		 * Filters the single site Members signup columns.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param array $value Array of columns to display.
+		 */
+		return apply_filters( 'bp_members_invitations_list_columns', array(
+			'cb'                       => '<input type="checkbox" />',
+			'invitee_email'            => __( 'Invitee', 'buddypress' ),
+			'username'                 => __( 'Inviter', 'buddypress' ),
+			'inviter_registered_date'  => __( 'Inviter Registered', 'buddypress' ),
+			'invitation_date_modified' => __( 'Date Modified', 'buddypress' ),
+			'invitation_sent'          => __( 'Email Sent', 'buddypress' ),
+			'invitation_accepted'      => __( 'Accepted', 'buddypress' )
+		) );
+	}
+
+	/**
+	 * Specific bulk actions for signups.
+	 *
+	 * @since 8.0.0
+	 */
+	public function get_bulk_actions() {
+		$actions = array(
+			'resend' => _x( 'Resend Email', 'Pending invitation action', 'buddypress' ),
+		);
+
+		if ( current_user_can( 'delete_users' ) ) {
+			$actions['delete'] = _x( 'Delete', 'Pending invitation action', 'buddypress' );
+		}
+
+		return $actions;
+	}
+
+	/**
+	 * The text shown when no items are found.
+	 *
+	 * Nice job, clean sheet!
+	 *
+	 * @since 8.0.0
+	 */
+	public function no_items() {
+
+		if ( bp_get_members_invitations_allowed() ) {
+			esc_html_e( 'No invitations found.', 'buddypress' );
+		} else {
+			$link = sprintf( '<a href="%1$s">%2$s</a>', esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-settings' ), 'admin.php' ) ) ), esc_html__( 'Edit settings', 'buddypress' ) );
+
+			/* translators: %s: url to site settings */
+			printf( __( 'Invitations are not allowed. %s', 'buddypress' ), $link );
+		}
+
+	}
+
+	/**
+	 * The columns invitations can be reordered by.
+	 *
+	 * @since 8.0.0
+	 */
+	public function get_sortable_columns() {
+		return array(
+			'invitee_email'            => 'invitee_email',
+			'username'                 => 'inviter_id',
+			'invitation_date_modified' => 'date_modified',
+			'invitation_sent'          => 'invite_sent',
+			'invitation_accepted'      => 'accepted',
+		);
+	}
+
+	/**
+	 * Display invitation rows.
+	 *
+	 * @since 8.0.0
+	 */
+	public function display_rows() {
+		$style = '';
+		foreach ( $this->items as $invite ) {
+			$style = ( ' class="alternate"' == $style ) ? '' : ' class="alternate"';
+			echo "\n\t" . $this->single_row( $invite, $style );
+		}
+	}
+
+	/**
+	 * Display an invitation row.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @see WP_List_Table::single_row() for explanation of params.
+	 *
+	 * @param BP_Invitation $invite   BP_Invitation object.
+	 * @param string        $style    Styles for the row.
+	 * @param string        $role     Role to be assigned to user.
+	 * @param int           $numposts Number of posts.
+	 * @return void
+	 */
+	public function single_row( $invite = null, $style = '', $role = '', $numposts = 0 ) {
+		echo '<tr' . $style . ' id="invitation-' . esc_attr( $invite->id ) . '">';
+		echo $this->single_row_columns( $invite );
+		echo '</tr>';
+	}
+
+	/**
+	 * Markup for the checkbox used to select items for bulk actions.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param BP_Invitation $invite BP_Invitation object.
+	 */
+	public function column_cb( $invite = null ) {
+	?>
+		<label class="screen-reader-text" for="invitation_<?php echo intval( $invite->id ); ?>"><?php
+			/* translators: accessibility text */
+			printf( esc_html__( 'Select invitation: %s', 'buddypress' ), $invite->id );
+		?></label>
+		<input type="checkbox" id="invitation_<?php echo intval( $invite->id ) ?>" name="invite_ids[]" value="<?php echo esc_attr( $invite->id ) ?>" />
+		<?php
+	}
+
+	/**
+	 * Markup for the checkbox used to select items for bulk actions.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param BP_Invitation $invite BP_Invitation object.
+	 */
+	public function column_invitee_email( $invite = null ) {
+		echo esc_html( $invite->invitee_email );
+
+		$actions = array();
+		$tools_url = bp_get_admin_url( 'tools.php' );
+
+		if ( is_network_admin() ) {
+			$tools_url = network_admin_url( 'admin.php' );
+		}
+
+		// Resend action only if pending
+		if ( ! $invite->accepted ) {
+			// Resend invitation email link.
+			$email_link = add_query_arg(
+				array(
+					'page'	    => 'bp-members-invitations',
+					'invite_id' => $invite->id,
+					'action'    => 'resend',
+				),
+				$tools_url
+			);
+
+			if ( ! $invite->invite_sent ) {
+				$resend_label = __( 'Send', 'buddypress' );
+			} else {
+				$resend_label = __( 'Resend', 'buddypress' );
+			}
+
+			$actions['resend'] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $email_link ), esc_html( $resend_label ) );
+		}
+
+		// Delete link. Could be cleanup or revoking the invitation.
+		$delete_link = add_query_arg(
+			array(
+				'page'      => 'bp-members-invitations',
+				'invite_id' => $invite->id,
+				'action'    => 'delete',
+			),
+			$tools_url
+		);
+
+		// Two cases: unsent and accepted (cleanup), and pending (cancels invite).
+		if ( ! $invite->invite_sent || $invite->accepted ) {
+			$actions['delete'] = sprintf( '<a href="%1$s" class="delete">%2$s</a>', esc_url( $delete_link ), esc_html__( 'Delete', 'buddypress' ) );
+		} else {
+			$actions['delete'] = sprintf( '<a href="%1$s" class="delete">%2$s</a>', esc_url( $delete_link ), esc_html__( 'Cancel', 'buddypress' ) );
+		}
+
+		/**
+		 * Filters the row actions for each invitation in list.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param array  $actions Array of actions and corresponding links.
+		 * @param object $invite  The BP_Invitation.
+		 */
+		$actions = apply_filters( 'bp_members_invitations_management_row_actions', $actions, $invite );
+
+		echo $this->row_actions( $actions );
+	}
+
+	/**
+	 * Display invited user's email address.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param BP_Invitation $invite BP_Invitation object.
+	 */
+	public function column_email( $invite = null ) {
+		printf( '<a href="mailto:%1$s">%2$s</a>', esc_attr( $invite->user_email ), esc_html( $invite->user_email ) );
+	}
+
+	/**
+	 * The inviter.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param BP_Invitation $invite BP_Invitation object.
+	 */
+	public function column_username( $invite = null ) {
+		$avatar  = get_avatar( $invite->inviter_id, 32 );
+		$inviter = get_user_by( 'id', $invite->inviter_id );
+		if ( ! $inviter ) {
+			return;
+		}
+
+		$user_link = bp_core_get_user_domain( $invite->inviter_id );
+
+		printf( '%1$s <strong><a href="%2$s" class="edit">%3$s</a></strong><br/>', $avatar, esc_url( $user_link ), esc_html( $inviter->user_login ) );
+	}
+
+	/**
+	 * Display invitation date.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param BP_Invitation $invite BP_Invitation object.
+	 */
+	public function column_inviter_registered_date( $invite = null ) {
+		$inviter = get_user_by( 'id', $invite->inviter_id );
+		if ( ! $inviter ) {
+			return;
+		}
+		echo esc_html( $inviter->user_registered );
+	}
+
+	/**
+	 * Display invitation date.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param BP_Invitation $invite BP_Invitation object.
+	 */
+	public function column_invitation_date_modified( $invite = null ) {
+		echo esc_html( $invite->date_modified );
+	}
+
+	/**
+	 * Display invitation date.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param BP_Invitation $invite BP_Invitation object.
+	 */
+	public function column_invitation_sent( $invite = null ) {
+		if ( $invite->invite_sent) {
+			esc_html_e( 'Yes', 'buddypress' );
+		} else {
+			esc_html_e( 'No', 'buddypress' );
+		}
+	}
+
+	/**
+	 * Display invitation acceptance status.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param BP_Invitation $invite BP_Invitation object.
+	 */
+	public function column_invitation_accepted( $invite = null ) {
+		if ( $invite->accepted ) {
+			esc_html_e( 'Yes', 'buddypress' );
+		} else {
+			esc_html_e( 'No', 'buddypress' );
+		}
+	}
+
+	/**
+	 * Allow plugins to add their custom column.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param BP_Invitation $invite      BP_Invitation object.
+	 * @param string        $column_name The column name.
+	 * @return string
+	 */
+	function column_default( $invite = null, $column_name = '' ) {
+
+		/**
+		 * Filters the single site custom columns for plugins.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param string $column_name The column name.
+		 * @param object $invite      The BP_Invitation object..
+		 */
+		return apply_filters( 'bp_members_invitations_management_custom_column', '', $column_name, $invite );
+	}
+}
diff --git src/bp-members/classes/class-bp-members-invitations-template.php src/bp-members/classes/class-bp-members-invitations-template.php
new file mode 100644
index 000000000..7f1bd91af
--- /dev/null
+++ src/bp-members/classes/class-bp-members-invitations-template.php
@@ -0,0 +1,348 @@
+<?php
+/**
+ * BuddyPress Members Invitation Template Loop Class.
+ *
+ * @package BuddyPress
+ * @subpackage TonificationsTemplate
+ * @since 8.0.0
+ */
+
+// Exit if accessed directly.
+defined( 'ABSPATH' ) || exit;
+
+/**
+ * The main membership invitations template loop class.
+ *
+ * Responsible for loading a group of membership invitations into a loop for display.
+ *
+ * @since 8.0.0
+ */
+class BP_Members_Invitations_Template {
+
+	/**
+	 * The loop iterator.
+	 *
+	 * @since 8.0.0
+	 * @var int
+	 */
+	public $current_invitation = -1;
+
+	/**
+	 * The number of invitations returned by the paged query.
+	 *
+	 * @since 8.0.0
+	 * @var int
+	 */
+	public $current_invitation_count;
+
+	/**
+	 * Total number of invitations matching the query.
+	 *
+	 * @since 8.0.0
+	 * @var int
+	 */
+	public $total_invitation_count;
+
+	/**
+	 * Array of network invitations located by the query.
+	 *
+	 * @since 8.0.0
+	 * @var array
+	 */
+	public $invitations;
+
+	/**
+	 * The invitation object currently being iterated on.
+	 *
+	 * @since 8.0.0
+	 * @var object
+	 */
+	public $invitation;
+
+	/**
+	 * A flag for whether the loop is currently being iterated.
+	 *
+	 * @since 8.0.0
+	 * @var bool
+	 */
+	public $in_the_loop;
+
+	/**
+	 * The ID of the user to whom the displayed invitations were sent.
+	 *
+	 * @since 8.0.0
+	 * @var int
+	 */
+	public $user_id;
+
+	/**
+	 * The ID of the user to whom the displayed invitations belong.
+	 *
+	 * @since 8.0.0
+	 * @var int
+	 */
+	public $inviter_id;
+
+	/**
+	 * The page number being requested.
+	 *
+	 * @since 8.0.0
+	 * @var int
+	 */
+	public $pag_page;
+
+	/**
+	 * The $_GET argument used in URLs for determining pagination.
+	 *
+	 * @since 8.0.0
+	 * @var int
+	 */
+	public $pag_arg;
+
+	/**
+	 * The number of items to display per page of results.
+	 *
+	 * @since 8.0.0
+	 * @var int
+	 */
+	public $pag_num;
+
+	/**
+	 * An HTML string containing pagination links.
+	 *
+	 * @since 8.0.0
+	 * @var string
+	 */
+	public $pag_links;
+
+	/**
+	 * A string to match against.
+	 *
+	 * @since 8.0.0
+	 * @var string
+	 */
+	public $search_terms;
+
+	/**
+	 * A database column to order the results by.
+	 *
+	 * @since 8.0.0
+	 * @var string
+	 */
+	public $order_by;
+
+	/**
+	 * The direction to sort the results (ASC or DESC).
+	 *
+	 * @since 8.0.0
+	 * @var string
+	 */
+	public $sort_order;
+
+	/**
+	 * Array of variables used in this invitation query.
+	 *
+	 * @since 8.0.0
+	 * @var array
+	 */
+	public $query_vars;
+
+	/**
+	 * Constructor method.
+	 *
+	 * @see bp_has_members_invitations() For information on the array format.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param array $args {
+	 *     An array of arguments. See {@link bp_has_members_invitations()}
+	 *     for more details.
+	 * }
+	 */
+	public function __construct( $args = array() ) {
+
+		// Parse arguments.
+		$r = wp_parse_args( $args, array(
+			'id'                => false,
+			'user_id'           => false,
+			'inviter_id'        => false,
+			'invitee_email'     => false,
+			'item_id'           => false,
+			'type'              => 'invite',
+			'invite_sent'       => 'all',
+			'accepted'          => 'all',
+			'search_terms'      => '',
+			'order_by'          => 'date_modified',
+			'sort_order'        => 'DESC',
+			'page'              => 1,
+			'per_page'          => 25,
+			'fields'            => 'all',
+			'page_arg'          => 'ipage',
+		) );
+
+		// Sort order direction.
+		$orders = array( 'ASC', 'DESC' );
+		if ( ! empty( $_GET['sort_order'] ) && in_array( $_GET['sort_order'], $orders ) ) {
+			$r['sort_order'] = $_GET['sort_order'];
+		} else {
+			$r['sort_order'] = in_array( $r['sort_order'], $orders ) ? $r['sort_order'] : 'DESC';
+		}
+
+		// Setup variables.
+		$this->pag_arg      = sanitize_key( $r['page_arg'] );
+		$this->pag_page     = bp_sanitize_pagination_arg( $this->pag_arg, $r['page']     );
+		$this->pag_num      = bp_sanitize_pagination_arg( 'num',          $r['per_page'] );
+		$this->user_id      = $r['user_id'];
+		$this->search_terms = $r['search_terms'];
+		$this->order_by     = $r['order_by'];
+		$this->sort_order   = $r['sort_order'];
+		$this->query_vars   = array(
+			'id'                => $r['id'],
+			'user_id'           => $r['user_id'],
+			'inviter_id'        => $r['inviter_id'],
+			'invitee_email'     => $r['invitee_email'],
+			'item_id'           => $r['item_id'],
+			'type'              => $r['type'],
+			'invite_sent'       => $r['invite_sent'],
+			'accepted'          => $r['accepted'],
+			'search_terms'      => $this->search_terms,
+			'order_by'          => $this->order_by,
+			'sort_order'        => $this->sort_order,
+			'page'              => $this->pag_page,
+			'per_page'          => $this->pag_num,
+		);
+
+		// Setup the invitations to loop through.
+		$invites_class = new BP_Members_Invitation_Manager();
+
+		$this->invitations              = $invites_class->get_invitations( $this->query_vars );
+		$this->current_invitation_count = count( $this->invitations );
+		$this->total_invitation_count   = $invites_class->get_invitations_total_count( $this->query_vars );
+
+		if ( (int) $this->total_invitation_count && (int) $this->pag_num ) {
+			$add_args = array(
+				'sort_order' => $this->sort_order,
+			);
+
+			$this->pag_links = paginate_links( array(
+				'base'      => add_query_arg( $this->pag_arg, '%#%' ),
+				'format'    => '',
+				'total'     => ceil( (int) $this->total_invitation_count / (int) $this->pag_num ),
+				'current'   => $this->pag_page,
+				'prev_text' => _x( '&larr;', 'Network invitation pagination previous text', 'buddypress' ),
+				'next_text' => _x( '&rarr;', 'Network invitation pagination next text',     'buddypress' ),
+				'mid_size'  => 1,
+				'add_args'  => $add_args,
+			) );
+		}
+	}
+
+	/**
+	 * Whether there are invitations available in the loop.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @see bp_has_members_invitations()
+	 *
+	 * @return bool True if there are items in the loop, otherwise false.
+	 */
+	public function has_invitations() {
+		if ( $this->current_invitation_count ) {
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Set up the next invitation and iterate index.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @return object The next invitation to iterate over.
+	 */
+	public function next_invitation() {
+
+		$this->current_invitation++;
+
+		$this->invitation = $this->invitations[ $this->current_invitation ];
+
+		return $this->invitation;
+	}
+
+	/**
+	 * Rewind the blogs and reset blog index.
+	 *
+	 * @since 8.0.0
+	 */
+	public function rewind_invitations() {
+
+		$this->current_invitation = -1;
+
+		if ( $this->current_invitation_count > 0 ) {
+			$this->invitation = $this->invitations[0];
+		}
+	}
+
+	/**
+	 * Whether there are invitations left in the loop to iterate over.
+	 *
+	 * This method is used by {@link bp_members_invitations()} as part of the
+	 * while loop that controls iteration inside the invitations loop, eg:
+	 *     while ( bp_members_invitations() ) { ...
+	 *
+	 * @since 8.0.0
+	 *
+	 * @see bp_members_invitations()
+	 *
+	 * @return bool True if there are more invitations to show,
+	 *              otherwise false.
+	 */
+	public function invitations() {
+
+		if ( $this->current_invitation + 1 < $this->current_invitation_count ) {
+			return true;
+
+		} elseif ( $this->current_invitation + 1 === $this->current_invitation_count ) {
+
+			/**
+			 * Fires right before the rewinding of invitation posts.
+			 *
+			 * @since 8.0.0
+			 */
+			do_action( 'members_invitations_loop_end' );
+
+			$this->rewind_invitations();
+		}
+
+		$this->in_the_loop = false;
+		return false;
+	}
+
+	/**
+	 * Set up the current invitation inside the loop.
+	 *
+	 * Used by {@link bp_the_invitation()} to set up the current
+	 * invitation data while looping, so that template tags used during
+	 * that iteration make reference to the current invitation.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @see bp_the_invitation()
+	 */
+	public function the_invitation() {
+		$this->in_the_loop = true;
+		$this->invitation  = $this->next_invitation();
+
+		// Loop has just started.
+		if ( 0 === $this->current_invitation ) {
+
+			/**
+			 * Fires if the current invitation item is the first in the invitation loop.
+			 *
+			 * @since 8.0.0
+			 */
+			do_action( 'members_invitations_loop_start' );
+		}
+	}
+}
diff --git src/bp-members/screens/list-invites.php src/bp-members/screens/list-invites.php
new file mode 100644
index 000000000..600cee733
--- /dev/null
+++ src/bp-members/screens/list-invites.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Members: Sent Invitations Status
+ *
+ * @package BuddyPress
+ * @subpackage MembersScreens
+ * @since 8.0.0
+ */
+
+/**
+ * Catch and process the Send Invites page.
+ *
+ * @since 8.0.0
+ */
+function members_screen_list_sent_invites() {
+
+	/**
+	 * Fires before the loading of template for the send membership invitations page.
+	 *
+	 * @since 8.0.0
+	 */
+	do_action( 'members_screen_list_sent_invites' );
+
+	/**
+	 * Filters the template used to display the send membership invitations page.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param string $template Path to the send membership invitations template to load.
+	 */
+	bp_core_load_template( apply_filters( 'members_template_list_sent_invites', 'members/single/invitations' ) );
+}
+
+/**
+ * Handle canceling or resending single invitations.
+ *
+ * @since 8.0.0
+ *
+ * @return bool
+ */
+function bp_members_invitations_action_handling() {
+
+	// Bail if not the read screen.
+	if ( ! bp_is_user_members_invitations_list() ) {
+		return false;
+	}
+
+	// Get the action.
+	$action = ! empty( $_GET['action']        ) ? $_GET['action']        : '';
+	$nonce  = ! empty( $_GET['_wpnonce']      ) ? $_GET['_wpnonce']      : '';
+	$id     = ! empty( $_GET['invitation_id'] ) ? $_GET['invitation_id'] : '';
+
+	// Bail if no action or no ID.
+	if ( empty( $action ) || empty( $id ) ) {
+		return false;
+	}
+
+	if ( 'cancel' === $action ) {
+		// Check the nonce and delete the invitation.
+		if ( bp_verify_nonce_request( 'bp_members_invitations_cancel_' . $id ) && bp_members_invitations_delete_by_id( $id ) ) {
+			bp_core_add_message( __( 'Invitation successfully canceled.', 'buddypress' ) );
+		} else {
+			bp_core_add_message( __( 'There was a problem canceling that invitation.', 'buddypress' ), 'error' );
+		}
+	} else if ( 'resend' === $action ) {
+		// Check the nonce and resend the invitation.
+		if ( bp_verify_nonce_request( 'bp_network_invitation_resend_' . $id ) && bp_members_invitation_resend_by_id( $id ) ) {
+			bp_core_add_message( __( 'Invitation successfully resent.', 'buddypress' ) );
+		} else {
+			bp_core_add_message( __( 'There was a problem resending that invitation.', 'buddypress' ), 'error' );
+		}
+	} else {
+		return false;
+	}
+
+	// Redirect.
+	$user_id = bp_displayed_user_id();
+	bp_core_redirect( bp_get_members_invitations_list_invites_permalink( $user_id ) );
+}
+add_action( 'bp_actions', 'bp_members_invitations_action_handling' );
diff --git src/bp-members/screens/register.php src/bp-members/screens/register.php
index 54b6facd5..b08f6ece8 100644
--- src/bp-members/screens/register.php
+++ src/bp-members/screens/register.php
@@ -42,9 +42,18 @@ function bp_core_screen_signup() {
 
 	$bp->signup->step = 'request-details';
 
-	if ( !bp_get_signup_allowed() ) {
-		$bp->signup->step = 'registration-disabled';
+	// Could the user be accepting an invitation?
+	$active_invite = false;
+	if ( bp_get_members_invitations_allowed() ) {
+		// Check to see if there's a valid invitation.
+		$maybe_invite = bp_get_members_invitation_from_request();
+		if ( $maybe_invite->id ) {
+			$active_invite = true;
+		}
+	}
 
+	if ( ! bp_get_signup_allowed() && ! $active_invite ) {
+		$bp->signup->step = 'registration-disabled';
 		// If the signup page is submitted, validate and save.
 	} elseif ( isset( $_POST['signup_submit'] ) && bp_verify_nonce_request( 'bp_new_signup' ) ) {
 
diff --git src/bp-members/screens/send-invites.php src/bp-members/screens/send-invites.php
new file mode 100644
index 000000000..6471ebf1d
--- /dev/null
+++ src/bp-members/screens/send-invites.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Members: Send Invitations
+ *
+ * @package BuddyPress
+ * @subpackage MembersScreens
+ * @since 8.0.0
+ */
+
+/**
+ * Catch and process the Send Invites page.
+ *
+ * @since 8.0.0
+ */
+function members_screen_send_invites() {
+
+	/**
+	 * Fires before the loading of template for the send membership invitations page.
+	 *
+	 * @since 8.0.0
+	 */
+	do_action( 'members_screen_send_invites' );
+
+	/**
+	 * Filters the template used to display the send membership invitations page.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param string $template Path to the send membership invitations template to load.
+	 */
+	bp_core_load_template( apply_filters( 'members_template_send_invites', 'members/single/invitations' ) );
+}
+
+/**
+ * Handle sending invitations.
+ *
+ * @since 8.0.0
+ *
+ * @return bool
+ */
+function bp_network_invitations_catch_send_action() {
+
+	// Bail if not the read screen.
+	if ( ! bp_is_user_members_invitations_send_screen() ) {
+		return false;
+	}
+
+	// Get the action.
+	$action  = ! empty( $_REQUEST['action']          ) ? $_REQUEST['action']          : '';
+	$nonce   = ! empty( $_REQUEST['_wpnonce']        ) ? $_REQUEST['_wpnonce']        : '';
+	$email   = ! empty( $_REQUEST['invitee_email']   ) ? $_REQUEST['invitee_email']   : '';
+	$message = ! empty( $_REQUEST['invite_message']  ) ? $_REQUEST['invite_message']  : '';
+
+	// Bail if missing required info.
+	if ( ( 'send-invite' !== $action ) ) {
+		return false;
+	}
+
+	$invite_args = array(
+		'invitee_email' => $email,
+		'inviter_id'    => bp_displayed_user_id(),
+		'content'       => $message,
+		'send_invite'   => 1
+	);
+
+	// Check the nonce and delete the invitation.
+	if ( bp_verify_nonce_request( 'bp_members_invitation_send_' . bp_displayed_user_id() ) && bp_members_invitations_invite_user( $invite_args ) ) {
+		bp_core_add_message( __( 'Invitation successfully sent!', 'buddypress' )          );
+	} else {
+		bp_core_add_message( __( 'There was a problem sending that invitation.', 'buddypress' ), 'error' );
+	}
+
+	// Redirect.
+	$user_id = bp_displayed_user_id();
+	bp_core_redirect( bp_get_members_invitations_send_invites_permalink( $user_id ) );
+}
+add_action( 'bp_actions', 'bp_network_invitations_catch_send_action' );
diff --git src/bp-templates/bp-legacy/buddypress-functions.php src/bp-templates/bp-legacy/buddypress-functions.php
index f4a3e1016..03c09ac00 100644
--- src/bp-templates/bp-legacy/buddypress-functions.php
+++ src/bp-templates/bp-legacy/buddypress-functions.php
@@ -2014,3 +2014,36 @@ function bp_legacy_theme_group_manage_members_add_search() {
 		<?php
 	endif;
 }
+
+/**
+ * Modify welcome message in Legacy template pack when
+ * community invitations are enabled.
+ *
+ * @since 8.0.0
+ *
+ * @return string $message The message text.
+ */
+function bp_members_invitations_add_legacy_welcome_message() {
+	$message = bp_members_invitations_get_registration_welcome_message();
+	if ( $message ) {
+		echo '<p>' . esc_html( $message ) . '</p>';
+	}
+}
+add_action( 'bp_before_register_page', 'bp_members_invitations_add_legacy_welcome_message' );
+
+
+/**
+ * Modify "registration disabled" message in Legacy template pack when
+ * community invitations are enabled.
+ *
+ * @since 8.0.0
+ *
+ * @return string $message The message text.
+ */
+function bp_members_invitations_add_legacy_registration_disabled_message() {
+	$message = bp_members_invitations_get_modified_registration_disabled_message();
+	if ( $message ) {
+		echo '<p>' . esc_html( $message ) . '</p>';
+	}
+}
+add_action( 'bp_after_registration_disabled', 'bp_members_invitations_add_legacy_registration_disabled_message' );
diff --git src/bp-templates/bp-legacy/buddypress/members/single/home.php src/bp-templates/bp-legacy/buddypress/members/single/home.php
index f56af6e9c..bed9da1bf 100644
--- src/bp-templates/bp-legacy/buddypress/members/single/home.php
+++ src/bp-templates/bp-legacy/buddypress/members/single/home.php
@@ -89,6 +89,9 @@
 		elseif ( bp_is_user_notifications() ) :
 			bp_get_template_part( 'members/single/notifications' );
 
+		elseif ( bp_is_user_members_invitations() ) :
+			bp_get_template_part( 'members/single/invitations' );
+
 		elseif ( bp_is_user_settings() ) :
 			bp_get_template_part( 'members/single/settings' );
 
diff --git src/bp-templates/bp-legacy/buddypress/members/single/invitations.php src/bp-templates/bp-legacy/buddypress/members/single/invitations.php
new file mode 100644
index 000000000..876a2e314
--- /dev/null
+++ src/bp-templates/bp-legacy/buddypress/members/single/invitations.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * BuddyPress - membership invitations
+ *
+ * @package BuddyPress
+ * @subpackage bp-legacy
+ * @version 8.0.0
+ */
+
+?>
+
+<div class="item-list-tabs no-ajax" id="subnav" aria-label="<?php esc_attr_e( 'Member secondary navigation', 'buddypress' ); ?>" role="navigation">
+	<ul>
+		<?php bp_get_options_nav(); ?>
+	</ul>
+</div>
+
+<?php
+switch ( bp_current_action() ) :
+
+	case 'send-invites' :
+		bp_get_template_part( 'members/single/invitations/send-invites' );
+		break;
+
+	case 'list-invites' :
+	default :
+		bp_get_template_part( 'members/single/invitations/list-invites' );
+		break;
+
+endswitch;
+
diff --git src/bp-templates/bp-legacy/buddypress/members/single/invitations/invitations-loop.php src/bp-templates/bp-legacy/buddypress/members/single/invitations/invitations-loop.php
new file mode 100644
index 000000000..f73857cc8
--- /dev/null
+++ src/bp-templates/bp-legacy/buddypress/members/single/invitations/invitations-loop.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * BuddyPress - Membership Invitations Loop
+ *
+ * @package BuddyPress
+ * @subpackage bp-legacy
+ * @version 8.0.0
+ */
+
+?>
+<form action="" method="post" id="invitations-bulk-management">
+	<table class="invitations">
+		<thead>
+			<tr>
+				<th class="icon"></th>
+				<th class="bulk-select-all"><input id="select-all-invitations" type="checkbox">
+					<label class="bp-screen-reader-text" for="select-all-invitations">
+						<?php
+						/* translators: accessibility text */
+						esc_html_e( 'Select all', 'buddypress' );
+						?>
+					</label>
+				</th>
+				<th class="title"><?php esc_html_e( 'Invitee', 'buddypress' ); ?></th>
+				<th class="content"><?php esc_html_e( 'Message', 'buddypress' ); ?></th>
+				<th class="sent"><?php esc_html_e( 'Sent', 'buddypress' ); ?></th>
+				<th class="accepted"><?php esc_html_e( 'Accepted', 'buddypress' ); ?></th>
+				<th class="date"><?php esc_html_e( 'Date Modified', 'buddypress' ); ?></th>
+				<th class="actions"><?php esc_html_e( 'Actions', 'buddypress' ); ?></th>
+			</tr>
+		</thead>
+
+		<tbody>
+
+			<?php while ( bp_the_members_invitations() ) : bp_the_members_invitation(); ?>
+
+				<tr>
+					<td></td>
+					<td class="bulk-select-check">
+						<label for="<?php bp_the_members_invitation_property( 'id', 'attribute' ); ?>">
+							<input id="<?php bp_the_members_invitation_property( 'id', 'attribute' ); ?>" type="checkbox" name="network_invitations[]" value="<?php bp_the_members_invitation_property( 'id', 'attribute' ); ?>" class="invitation-check">
+							<span class="bp-screen-reader-text">
+								<?php
+									/* translators: accessibility text */
+									esc_html_e( 'Select this invitation', 'buddypress' );
+								?>
+							</span>
+						</label>
+					</td>
+					<td class="invitation-invitee"><?php bp_the_members_invitation_property( 'invitee_email' );  ?></td>
+					<td class="invitation-content"><?php bp_the_members_invitation_property( 'content' );  ?></td>
+					<td class="invitation-sent"><?php bp_the_members_invitation_property( 'invite_sent' );  ?></td>
+					<td class="invitation-accepted"><?php bp_the_members_invitation_property( 'accepted' );  ?></td>
+					<td class="invitation-date-modified"><?php bp_the_members_invitation_property( 'date_modified' );   ?></td>
+					<td class="invitation-actions"><?php bp_the_members_invitation_action_links(); ?></td>
+				</tr>
+
+			<?php endwhile; ?>
+
+		</tbody>
+	</table>
+
+	<div class="invitations-options-nav">
+		<?php // @TODO //bp_invitations_bulk_management_dropdown(); ?>
+	</div><!-- .invitations-options-nav -->
+
+	<?php wp_nonce_field( 'invitations_bulk_nonce', 'invitations_bulk_nonce' ); ?>
+</form>
diff --git src/bp-templates/bp-legacy/buddypress/members/single/invitations/list-invites.php src/bp-templates/bp-legacy/buddypress/members/single/invitations/list-invites.php
new file mode 100644
index 000000000..8e299f1d6
--- /dev/null
+++ src/bp-templates/bp-legacy/buddypress/members/single/invitations/list-invites.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * BuddyPress - Sent Membership Invitations
+ *
+ * @package BuddyPress
+ * @subpackage bp-legacy
+ * @version 8.0.0
+ */
+?>
+
+<?php if ( bp_has_members_invitations() ) : ?>
+
+	<h2 class="bp-screen-reader-text">
+		<?php
+		/* translators: accessibility text */
+		esc_html_e( 'Invitations', 'buddypress' );
+		?>
+	</h2>
+
+	<div id="pag-top" class="pagination no-ajax">
+		<div class="pag-count" id="invitations-count-top">
+			<?php bp_members_invitations_pagination_count(); ?>
+		</div>
+
+		<div class="pagination-links" id="invitations-pag-top">
+			<?php bp_members_invitations_pagination_links(); ?>
+		</div>
+	</div>
+
+	<?php bp_get_template_part( 'members/single/invitations/invitations-loop' ); ?>
+
+	<div id="pag-bottom" class="pagination no-ajax">
+		<div class="pag-count" id="invitations-count-bottom">
+			<?php bp_members_invitations_pagination_count(); ?>
+		</div>
+
+		<div class="pagination-links" id="invitations-pag-bottom">
+			<?php bp_members_invitations_pagination_links(); ?>
+		</div>
+	</div>
+
+<?php else : ?>
+
+	<p><?php esc_html_e( 'There are no invitations to display.', 'buddypress' ); ?></p>
+
+<?php endif;
diff --git src/bp-templates/bp-legacy/buddypress/members/single/invitations/send-invites.php src/bp-templates/bp-legacy/buddypress/members/single/invitations/send-invites.php
new file mode 100644
index 000000000..6eeb3b62f
--- /dev/null
+++ src/bp-templates/bp-legacy/buddypress/members/single/invitations/send-invites.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * BuddyPress - Sent Membership Invitations
+ *
+ * @package BuddyPress
+ * @subpackage bp-legacy
+ * @version 8.0.0
+ */
+?>
+<h2 class="bp-screen-reader-text">
+	<?php
+	/* translators: accessibility text */
+	esc_html_e( 'Send Invitations', 'buddypress' );
+	?>
+</h2>
+
+<form class="standard-form members-invitation-form" id="members-invitation-form" method="post">
+	<p class="description"><?php esc_html_e( 'Fill out the form below to invite a new user to join this site. Upon submission of the form, an email will be sent to the invitee containing a link to accept your invitation. You may also add a custom message to the email.', 'buddypress' ); ?></p>
+
+	<label for="bp_members_invitation_invitee_email"><?php esc_html_e( 'Email address of new user', 'buddypress' ); ?></label>
+	<input id="bp_members_invitation_invitee_email" type="email" name="invitee_email" required="required">
+
+	<label for="bp_members_invitation_message"><?php esc_html_e( 'Add a personalized message to the invitation (optional)', 'buddypress' ); ?></label>
+	<textarea id="bp_members_invitation_message" name="invite_message"></textarea>
+
+	<input type="hidden" name="action" value="send-invite">
+
+	<?php wp_nonce_field( 'bp_members_invitation_send_' . bp_displayed_user_id() ) ?>
+	<p>
+		<input id="submit" type="submit" name="submit" class="submit" value="<?php esc_attr_e( 'Send Invitation', 'buddypress' ) ?>" />
+	</p>
+</form>
diff --git src/bp-templates/bp-nouveau/buddypress-functions.php src/bp-templates/bp-nouveau/buddypress-functions.php
index 892bf2e33..f93134f74 100644
--- src/bp-templates/bp-nouveau/buddypress-functions.php
+++ src/bp-templates/bp-nouveau/buddypress-functions.php
@@ -195,6 +195,9 @@ class BP_Nouveau extends BP_Theme_Compat {
 		// Set the BP Uri for the Ajax customizer preview.
 		add_filter( 'bp_uri', array( $this, 'customizer_set_uri' ), 10, 1 );
 
+		// Modify "registration disabled" and welcome message if invitations are enabled.
+		add_action( 'bp_nouveau_feedback_messages', array( $this, 'filter_registration_messages' ), 99 );
+
 		/** Override **********************************************************/
 
 		/**
@@ -676,6 +679,29 @@ class BP_Nouveau extends BP_Theme_Compat {
 
 		return $path;
 	}
+	/**
+	 * Modify "registration disabled" message in Nouveau template pack.
+	 * Modify welcome message in Nouveau template pack.
+	 *
+	 * @since 8.0.0
+	 *
+	 * @param array $messages The list of feedback messages.
+	 *
+	 * @return array $messages
+	 */
+	function filter_registration_messages( $messages ) {
+		// Change the "registration is disabled" message.
+		$disallowed_message = bp_members_invitations_get_modified_registration_disabled_message();
+		if ( $disallowed_message ) {
+			$messages['registration-disabled']['message'] = $disallowed_message;
+		}
+		// Add information about invitations to the welcome block.
+		$welcome_message = bp_members_invitations_get_registration_welcome_message();
+		if ( $welcome_message ) {
+			$messages['request-details']['message'] = $welcome_message . $messages['request-details']['message'];
+		}
+		return $messages;
+	}
 }
 
 /**
diff --git src/bp-templates/bp-nouveau/buddypress/members/single/invitations.php src/bp-templates/bp-nouveau/buddypress/members/single/invitations.php
new file mode 100644
index 000000000..1fd36bab1
--- /dev/null
+++ src/bp-templates/bp-nouveau/buddypress/members/single/invitations.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * BuddyPress - Membership invitations
+ *
+ * @since 8.0.0
+ * @version 8.0.0
+ */
+?>
+
+<nav class="<?php bp_nouveau_single_item_subnav_classes(); ?>" id="subnav" role="navigation" aria-label="<?php esc_attr_e( 'Groups menu', 'buddypress' ); ?>">
+	<ul class="subnav">
+		<?php bp_get_template_part( 'members/single/parts/item-subnav' ); ?>
+	</ul>
+</nav><!-- .bp-navs -->
+
+<?php
+switch ( bp_current_action() ) :
+
+	case 'send-invites' :
+		bp_get_template_part( 'members/single/invitations/send-invites' );
+		break;
+
+	case 'list-invites' :
+	default :
+		bp_get_template_part( 'members/single/invitations/list-invites' );
+		break;
+
+endswitch;
+
diff --git src/bp-templates/bp-nouveau/buddypress/members/single/invitations/invitations-loop.php src/bp-templates/bp-nouveau/buddypress/members/single/invitations/invitations-loop.php
new file mode 100644
index 000000000..f4aa643ee
--- /dev/null
+++ src/bp-templates/bp-nouveau/buddypress/members/single/invitations/invitations-loop.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * BuddyPress - Membership Invitations Loop
+ *
+ * @since 8.0.0
+ * @version 8.0.0
+ */
+?>
+<form action="" method="post" id="invitations-bulk-management" class="standard-form">
+	<table class="invitations">
+		<thead>
+			<tr>
+				<th class="bulk-select-all"><input id="select-all-invitations" type="checkbox">
+					<label class="bp-screen-reader-text" for="select-all-invitations">
+						<?php
+						/* translators: accessibility text */
+						esc_html_e( 'Select all', 'buddypress' );
+						?>
+					</label>
+				</th>
+				<th class="title"><?php esc_html_e( 'Invitee', 'buddypress' ); ?></th>
+				<th class="content"><?php esc_html_e( 'Message', 'buddypress' ); ?></th>
+				<th class="sent"><?php esc_html_e( 'Sent', 'buddypress' ); ?></th>
+				<th class="accepted"><?php esc_html_e( 'Accepted', 'buddypress' ); ?></th>
+				<th class="date"><?php esc_html_e( 'Date Modified', 'buddypress' ); ?></th>
+				<th class="actions"><?php esc_html_e( 'Actions', 'buddypress' ); ?></th>
+			</tr>
+		</thead>
+
+		<tbody>
+
+			<?php while ( bp_the_members_invitations() ) : bp_the_members_invitation(); ?>
+
+				<tr>
+					<td class="bulk-select-check">
+						<label for="<?php bp_the_members_invitation_property( 'id', 'attribute' ); ?>">
+							<input id="<?php bp_the_members_invitation_property( 'id', 'attribute' ); ?>" type="checkbox" name="network_invitations[]" value="<?php bp_the_members_invitation_property( 'id', 'attribute' ); ?>" class="invitation-check">
+							<span class="bp-screen-reader-text">
+								<?php
+									/* translators: accessibility text */
+									esc_html_e( 'Select this invitation', 'buddypress' );
+								?>
+							</span>
+						</label>
+					</td>
+					<td class="invitation-invitee"><?php bp_the_members_invitation_property( 'invitee_email' ); ?></td>
+					<td class="invitation-content"><?php bp_the_members_invitation_property( 'content' ); ?></td>
+					<td class="invitation-sent"><?php bp_the_members_invitation_property( 'invite_sent' ); ?></td>
+					<td class="invitation-accepted"><?php bp_the_members_invitation_property( 'accepted' ); ?></td>
+					<td class="invitation-date-modified"><?php bp_the_members_invitation_property( 'date_modified' ); ?></td>
+					<td class="invitation-actions"><?php bp_the_members_invitation_action_links(); ?></td>
+				</tr>
+
+			<?php endwhile; ?>
+
+		</tbody>
+	</table>
+
+	<div class="invitations-options-nav">
+		<?php bp_nouveau_invitations_bulk_management_dropdown(); ?>
+	</div><!-- .invitations-options-nav -->
+
+	<?php wp_nonce_field( 'invitations_bulk_nonce', 'invitations_bulk_nonce' ); ?>
+</form>
diff --git src/bp-templates/bp-nouveau/buddypress/members/single/invitations/list-invites.php src/bp-templates/bp-nouveau/buddypress/members/single/invitations/list-invites.php
new file mode 100644
index 000000000..a83054098
--- /dev/null
+++ src/bp-templates/bp-nouveau/buddypress/members/single/invitations/list-invites.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * BuddyPress - Pending Membership Invitations
+ *
+ * @since 8.0.0
+ * @version 8.0.0
+ */
+?>
+
+<?php if ( bp_has_members_invitations() ) : ?>
+
+	<h2 class="bp-screen-reader-text">
+		<?php
+		/* translators: accessibility text */
+		esc_html_e( 'Invitations', 'buddypress' );
+		?>
+	</h2>
+
+	<div id="pag-top" class="bp-pagination no-ajax">
+		<div class="pag-count" id="invitations-count-top">
+			<?php bp_members_invitations_pagination_count(); ?>
+		</div>
+
+		<div class="pagination-links" id="invitations-pag-top">
+			<?php bp_members_invitations_pagination_links(); ?>
+		</div>
+	</div>
+
+	<?php bp_get_template_part( 'members/single/invitations/invitations-loop' ); ?>
+
+	<div id="pag-bottom" class="bp-pagination no-ajax">
+		<div class="pag-count" id="invitations-count-bottom">
+			<?php bp_members_invitations_pagination_count(); ?>
+		</div>
+
+		<div class="pagination-links" id="invitations-pag-bottom">
+			<?php bp_members_invitations_pagination_links(); ?>
+		</div>
+	</div>
+
+<?php else : ?>
+
+	<?php bp_nouveau_user_feedback( 'member-invites-none' ); ?>
+
+<?php endif;
diff --git src/bp-templates/bp-nouveau/buddypress/members/single/invitations/send-invites.php src/bp-templates/bp-nouveau/buddypress/members/single/invitations/send-invites.php
new file mode 100644
index 000000000..077c1fa24
--- /dev/null
+++ src/bp-templates/bp-nouveau/buddypress/members/single/invitations/send-invites.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * BuddyPress - Send a Membership Invitation.
+ *
+ * @since 8.0.0
+ * @version 8.0.0
+ */
+?>
+<h2 class="bp-screen-reader-text">
+	<?php
+	/* translators: accessibility text */
+	esc_html_e( 'Send Invitation', 'buddypress' );
+	?>
+</h2>
+
+<p class="bp-feedback info">
+	<span class="bp-icon" aria-hidden="true"></span>
+	<span class="bp-help-text">
+		<?php esc_html_e( 'Fill out the form below to invite a new user to join this site. Upon submission of the form, an email will be sent to the invitee containing a link to accept your invitation. You may also add a custom message to the email.', 'buddypress' ); ?>
+	</span>
+</p>
+
+<form class="standard-form network-invitation-form" id="network-invitation-form" method="post">
+	<label for="bp_members_invitation_invitee_email">
+		<?php esc_html_e( 'Email', 'buddypress' ); ?>
+		<span class="bp-required-field-label"><?php esc_html_e( '(required)', 'buddypress' ); ?></span>
+	</label>
+	<input id="bp_members_invitation_invitee_email" type="email" name="invitee_email" required="required">
+
+	<label for="bp_members_invitation_message">
+		<?php esc_html_e( 'Add a personalized message to the invitation (optional)', 'buddypress' ); ?>
+	</label>
+	<textarea id="bp_members_invitation_message" name="invite_message"></textarea>
+
+	<input type="hidden" name="action" value="send-invite">
+
+	<?php bp_nouveau_submit_button( 'member-send-invite' ); ?>
+</form>
diff --git src/bp-templates/bp-nouveau/common-styles/_bp_filters.scss src/bp-templates/bp-nouveau/common-styles/_bp_filters.scss
index 8ff5970f1..1317aee14 100644
--- src/bp-templates/bp-nouveau/common-styles/_bp_filters.scss
+++ src/bp-templates/bp-nouveau/common-styles/_bp_filters.scss
@@ -181,13 +181,11 @@
 
 	} // close .subnav-filters
 
-	.notifications-options-nav {
-
-		input#notification-bulk-manage {
-			border: 0;
-			border-radius: 0;
-			line-height: 1.6;
-		}
+	.notifications-options-nav input#notification-bulk-manage,
+	.invitations-options-nav input#invitation-bulk-manage {
+		border: 0;
+		border-radius: 0;
+		line-height: 1.6;
 	}
 
 	.group-subnav-filters {
diff --git src/bp-templates/bp-nouveau/common-styles/_bp_forms.scss src/bp-templates/bp-nouveau/common-styles/_bp_forms.scss
index b39d8a03c..9453a4452 100644
--- src/bp-templates/bp-nouveau/common-styles/_bp_forms.scss
+++ src/bp-templates/bp-nouveau/common-styles/_bp_forms.scss
@@ -24,7 +24,8 @@
 		opacity: 0.4;
 	}
 
-	#notification-bulk-manage[disabled] {
+	#notification-bulk-manage[disabled],
+	#invitation-bulk-manage[disabled] {
 		display: none;
 	}
 
@@ -399,11 +400,9 @@ body.no-js {
 
 	@include medium-small-up() {
 
-		.notifications-options-nav {
-
-			.select-wrap {
-				float: left;
-			}
+		.notifications-options-nav .select-wrap,
+		.invitations-options-nav .select-wrap {
+			float: left;
 		}
 	}
 }
diff --git src/bp-templates/bp-nouveau/common-styles/_bp_generic_and_typography.scss src/bp-templates/bp-nouveau/common-styles/_bp_generic_and_typography.scss
index 65cabf5e7..2d2799368 100644
--- src/bp-templates/bp-nouveau/common-styles/_bp_generic_and_typography.scss
+++ src/bp-templates/bp-nouveau/common-styles/_bp_generic_and_typography.scss
@@ -255,7 +255,8 @@ body.buddypress {
 		}
 	}
 
-	#notification-select {
+	#notification-select,
+	#invitation-select {
 
 		@include responsive-font(14);
 	}
diff --git src/bp-templates/bp-nouveau/css/buddypress-rtl.css src/bp-templates/bp-nouveau/css/buddypress-rtl.css
index 35b21b66d..20f7c1a32 100644
--- src/bp-templates/bp-nouveau/css/buddypress-rtl.css
+++ src/bp-templates/bp-nouveau/css/buddypress-rtl.css
@@ -255,12 +255,14 @@ body.buddypress article.page > .entry-header:not(.alignwide):not(.alignfull) .en
 	}
 }
 
-.buddypress-wrap #notification-select {
+.buddypress-wrap #notification-select,
+.buddypress-wrap #invitation-select {
 	font-size: 12px;
 }
 
 @media screen and (min-width: 46.8em) {
-	.buddypress-wrap #notification-select {
+	.buddypress-wrap #notification-select,
+	.buddypress-wrap #invitation-select {
 		font-size: 14px;
 	}
 }
@@ -794,7 +796,8 @@ body.buddypress article.page > .entry-header:not(.alignwide):not(.alignfull) .en
 	}
 }
 
-.buddypress-wrap .notifications-options-nav input#notification-bulk-manage {
+.buddypress-wrap .notifications-options-nav input#notification-bulk-manage,
+.buddypress-wrap .invitations-options-nav input#invitation-bulk-manage {
 	border: 0;
 	border-radius: 0;
 	line-height: 1.6;
@@ -3430,7 +3433,8 @@ body.buddypress.settings.data #buddypress.buddypress-wrap .item-body p a {
 	opacity: 0.4;
 }
 
-.buddypress-wrap #notification-bulk-manage[disabled] {
+.buddypress-wrap #notification-bulk-manage[disabled],
+.buddypress-wrap #invitation-bulk-manage[disabled] {
 	display: none;
 }
 
@@ -3727,7 +3731,8 @@ body.no-js .buddypress #messages-bulk-management #select-all-messages {
 }
 
 @media screen and (min-width: 32em) {
-	.buddypress-wrap .notifications-options-nav .select-wrap {
+	.buddypress-wrap .notifications-options-nav .select-wrap,
+	.buddypress-wrap .invitations-options-nav .select-wrap {
 		float: right;
 	}
 }
diff --git src/bp-templates/bp-nouveau/css/buddypress.css src/bp-templates/bp-nouveau/css/buddypress.css
index 2196e878f..7cc80ca7f 100644
--- src/bp-templates/bp-nouveau/css/buddypress.css
+++ src/bp-templates/bp-nouveau/css/buddypress.css
@@ -255,12 +255,14 @@ body.buddypress article.page > .entry-header:not(.alignwide):not(.alignfull) .en
 	}
 }
 
-.buddypress-wrap #notification-select {
+.buddypress-wrap #notification-select,
+.buddypress-wrap #invitation-select {
 	font-size: 12px;
 }
 
 @media screen and (min-width: 46.8em) {
-	.buddypress-wrap #notification-select {
+	.buddypress-wrap #notification-select,
+	.buddypress-wrap #invitation-select {
 		font-size: 14px;
 	}
 }
@@ -794,7 +796,8 @@ body.buddypress article.page > .entry-header:not(.alignwide):not(.alignfull) .en
 	}
 }
 
-.buddypress-wrap .notifications-options-nav input#notification-bulk-manage {
+.buddypress-wrap .notifications-options-nav input#notification-bulk-manage,
+.buddypress-wrap .invitations-options-nav input#invitation-bulk-manage {
 	border: 0;
 	border-radius: 0;
 	line-height: 1.6;
@@ -3430,7 +3433,8 @@ body.buddypress.settings.data #buddypress.buddypress-wrap .item-body p a {
 	opacity: 0.4;
 }
 
-.buddypress-wrap #notification-bulk-manage[disabled] {
+.buddypress-wrap #notification-bulk-manage[disabled],
+.buddypress-wrap #invitation-bulk-manage[disabled] {
 	display: none;
 }
 
@@ -3727,7 +3731,8 @@ body.no-js .buddypress #messages-bulk-management #select-all-messages {
 }
 
 @media screen and (min-width: 32em) {
-	.buddypress-wrap .notifications-options-nav .select-wrap {
+	.buddypress-wrap .notifications-options-nav .select-wrap,
+	.buddypress-wrap .invitations-options-nav .select-wrap {
 		float: left;
 	}
 }
diff --git src/bp-templates/bp-nouveau/css/twentytwentyone-rtl.css src/bp-templates/bp-nouveau/css/twentytwentyone-rtl.css
index 453826cd5..d3d05a346 100644
--- src/bp-templates/bp-nouveau/css/twentytwentyone-rtl.css
+++ src/bp-templates/bp-nouveau/css/twentytwentyone-rtl.css
@@ -154,11 +154,13 @@ Hello, this is the BP Nouveau's Twenty Twenty-One companion stylesheet.
 	padding-right: 0;
 }
 
-#buddypress.twentytwentyone .notifications-options-nav {
+#buddypress.twentytwentyone .notifications-options-nav,
+#buddypress.twentytwentyone .invitations-options-nav {
 	margin-top: 1em;
 }
 
-#buddypress.twentytwentyone .notifications-options-nav input#notification-bulk-manage {
+#buddypress.twentytwentyone .notifications-options-nav input#notification-bulk-manage,
+#buddypress.twentytwentyone .invitations-options-nav input#invitation-bulk-manage {
 	line-height: 1.2;
 }
 
diff --git src/bp-templates/bp-nouveau/css/twentytwentyone.css src/bp-templates/bp-nouveau/css/twentytwentyone.css
index ecfaf8d9e..a8837db02 100644
--- src/bp-templates/bp-nouveau/css/twentytwentyone.css
+++ src/bp-templates/bp-nouveau/css/twentytwentyone.css
@@ -154,11 +154,13 @@ Hello, this is the BP Nouveau's Twenty Twenty-One companion stylesheet.
 	padding-left: 0;
 }
 
-#buddypress.twentytwentyone .notifications-options-nav {
+#buddypress.twentytwentyone .notifications-options-nav,
+#buddypress.twentytwentyone .invitations-options-nav {
 	margin-top: 1em;
 }
 
-#buddypress.twentytwentyone .notifications-options-nav input#notification-bulk-manage {
+#buddypress.twentytwentyone .notifications-options-nav input#notification-bulk-manage,
+#buddypress.twentytwentyone .invitations-options-nav input#invitation-bulk-manage {
 	line-height: 1.2;
 }
 
diff --git src/bp-templates/bp-nouveau/includes/functions.php src/bp-templates/bp-nouveau/includes/functions.php
index 9ee9b52c5..1b17c6294 100644
--- src/bp-templates/bp-nouveau/includes/functions.php
+++ src/bp-templates/bp-nouveau/includes/functions.php
@@ -927,6 +927,7 @@ function bp_nouveau_theme_cover_image( $params = array() ) {
  * All user feedback messages are available here
  *
  * @since 3.0.0
+ * @since 8.0.0 Adds the 'member-invites-none' feedback.
  *
  * @param string $feedback_id The ID of the message.
  *
@@ -939,154 +940,162 @@ function bp_nouveau_get_user_feedback( $feedback_id = '' ) {
 	 * Use this filter to add your custom feedback messages.
 	 *
 	 * @since 3.0.0
+	 * @since 8.0.0 Adds the 'member-invites-none' feedback.
 	 *
 	 * @param array $value The list of feedback messages.
 	 */
-	$feedback_messages = apply_filters( 'bp_nouveau_feedback_messages', array(
-		'registration-disabled' => array(
-			'type'    => 'info',
-			'message' => __( 'Member registration is currently not allowed.', 'buddypress' ),
-			'before'  => 'bp_before_registration_disabled',
-			'after'   => 'bp_after_registration_disabled'
-		),
-		'request-details' => array(
-			'type'    => 'info',
-			'message' => __( 'Registering for this site is easy. Just fill in the fields below, and we\'ll get a new account set up for you in no time.', 'buddypress' ),
-			'before'  => false,
-			'after'   => false,
-		),
-		'completed-confirmation' => array(
-			'type'    => 'info',
-			'message' => __( 'You have successfully created your account! Please log in using the username and password you have just created.', 'buddypress' ),
-			'before'  => 'bp_before_registration_confirmed',
-			'after'   => 'bp_after_registration_confirmed',
-		),
-		'directory-activity-loading' => array(
-			'type'    => 'loading',
-			'message' => __( 'Loading the community updates. Please wait.', 'buddypress' ),
-		),
-		'single-activity-loading' => array(
-			'type'    => 'loading',
-			'message' => __( 'Loading the update. Please wait.', 'buddypress' ),
-		),
-		'activity-loop-none' => array(
-			'type'    => 'info',
-			'message' => __( 'Sorry, there was no activity found. Please try a different filter.', 'buddypress' ),
-		),
-		'blogs-loop-none' => array(
-			'type'    => 'info',
-			'message' => __( 'Sorry, there were no sites found.', 'buddypress' ),
-		),
-		'blogs-no-signup' => array(
-			'type'    => 'info',
-			'message' => __( 'Site registration is currently disabled.', 'buddypress' ),
-		),
-		'directory-blogs-loading' => array(
-			'type'    => 'loading',
-			'message' => __( 'Loading the sites of the network. Please wait.', 'buddypress' ),
-		),
-		'directory-groups-loading' => array(
-			'type'    => 'loading',
-			'message' => __( 'Loading the groups of the community. Please wait.', 'buddypress' ),
-		),
-		'groups-loop-none' => array(
-			'type'    => 'info',
-			'message' => __( 'Sorry, there were no groups found.', 'buddypress' ),
-		),
-		'group-activity-loading' => array(
-			'type'    => 'loading',
-			'message' => __( 'Loading the group updates. Please wait.', 'buddypress' ),
-		),
-		'group-members-loading' => array(
-			'type'    => 'loading',
-			'message' => __( 'Requesting the group members. Please wait.', 'buddypress' ),
-		),
-		'group-members-none' => array(
-			'type'    => 'info',
-			'message' => __( 'Sorry, there were no group members found.', 'buddypress' ),
-		),
-		'group-members-search-none' => array(
-			'type'    => 'info',
-			'message' => __( 'Sorry, there was no member of that name found in this group.', 'buddypress' ),
-		),
-		'group-manage-members-none' => array(
-			'type'    => 'info',
-			'message' => __( 'This group has no members.', 'buddypress' ),
-		),
-		'group-requests-none' => array(
-			'type'    => 'info',
-			'message' => __( 'There are no pending membership requests.', 'buddypress' ),
-		),
-		'group-requests-loading' => array(
-			'type'    => 'loading',
-			'message' => __( 'Loading the members who requested to join the group. Please wait.', 'buddypress' ),
-		),
-		'group-delete-warning' => array(
-			'type'    => 'warning',
-			'message' => __( 'WARNING: Deleting this group will completely remove ALL content associated with it. There is no way back. Please be careful with this option.', 'buddypress' ),
-		),
-		'group-avatar-delete-info' => array(
-			'type'    => 'info',
-			'message' => __( 'If you\'d like to remove the existing group profile photo but not upload a new one, please use the delete group profile photo button.', 'buddypress' ),
-		),
-		'directory-members-loading' => array(
-			'type'    => 'loading',
-			'message' => __( 'Loading the members of your community. Please wait.', 'buddypress' ),
-		),
-		'members-loop-none' => array(
-			'type'    => 'info',
-			'message' => __( 'Sorry, no members were found.', 'buddypress' ),
-		),
-		'member-requests-none' => array(
-			'type'    => 'info',
-			'message' => __( 'You have no pending friendship requests.', 'buddypress' ),
-		),
-		'member-invites-none' => array(
-			'type'    => 'info',
-			'message' => __( 'You have no outstanding group invites.', 'buddypress' ),
-		),
-		'member-notifications-none' => array(
-			'type'    => 'info',
-			'message' => __( 'This member has no notifications.', 'buddypress' ),
-		),
-		'member-wp-profile-none' => array(
-			'type'    => 'info',
-			/* translators: %s: member name */
-			'message' => __( '%s did not save any profile information yet.', 'buddypress' ),
-		),
-		'member-delete-account' => array(
-			'type'    => 'warning',
-			'message' => __( 'Deleting this account will delete all of the content it has created. It will be completely unrecoverable.', 'buddypress' ),
-		),
-		'member-activity-loading' => array(
-			'type'    => 'loading',
-			'message' => __( 'Loading the member\'s updates. Please wait.', 'buddypress' ),
-		),
-		'member-blogs-loading' => array(
-			'type'    => 'loading',
-			'message' => __( 'Loading the member\'s blogs. Please wait.', 'buddypress' ),
-		),
-		'member-friends-loading' => array(
-			'type'    => 'loading',
-			'message' => __( 'Loading the member\'s friends. Please wait.', 'buddypress' ),
-		),
-		'member-groups-loading' => array(
-			'type'    => 'loading',
-			'message' => __( 'Loading the member\'s groups. Please wait.', 'buddypress' ),
-		),
-		'member-notifications-loading' => array(
-			'type'    => 'loading',
-			'message' => __( 'Loading notifications. Please wait.', 'buddypress' ),
-		),
-		'member-group-invites-all' => array(
-			'type'    => 'info',
-			'message' => __( 'Currently every member of the community can invite you to join their groups. If you are not comfortable with it, you can always restrict group invites to your friends only.', 'buddypress' ),
-		),
-		'member-group-invites-friends-only' => array(
-			'type'    => 'info',
-			'message' => __( 'Currently only your friends can invite you to groups. Uncheck the box to allow any member to send invites.', 'buddypress' ),
-		),
-	) );
+	$feedback_messages = apply_filters(
+		'bp_nouveau_feedback_messages',
+		array(
+			'registration-disabled'             => array(
+				'type'    => 'info',
+				'message' => __( 'Member registration is currently not allowed.', 'buddypress' ),
+				'before'  => 'bp_before_registration_disabled',
+				'after'   => 'bp_after_registration_disabled'
+			),
+			'request-details'                   => array(
+				'type'    => 'info',
+				'message' => __( 'Registering for this site is easy. Just fill in the fields below, and we\'ll get a new account set up for you in no time.', 'buddypress' ),
+				'before'  => false,
+				'after'   => false,
+			),
+			'completed-confirmation'            => array(
+				'type'    => 'info',
+				'message' => __( 'You have successfully created your account! Please log in using the username and password you have just created.', 'buddypress' ),
+				'before'  => 'bp_before_registration_confirmed',
+				'after'   => 'bp_after_registration_confirmed',
+			),
+			'directory-activity-loading'        => array(
+				'type'    => 'loading',
+				'message' => __( 'Loading the community updates. Please wait.', 'buddypress' ),
+			),
+			'single-activity-loading'           => array(
+				'type'    => 'loading',
+				'message' => __( 'Loading the update. Please wait.', 'buddypress' ),
+			),
+			'activity-loop-none'                => array(
+				'type'    => 'info',
+				'message' => __( 'Sorry, there was no activity found. Please try a different filter.', 'buddypress' ),
+			),
+			'blogs-loop-none'                   => array(
+				'type'    => 'info',
+				'message' => __( 'Sorry, there were no sites found.', 'buddypress' ),
+			),
+			'blogs-no-signup'                   => array(
+				'type'    => 'info',
+				'message' => __( 'Site registration is currently disabled.', 'buddypress' ),
+			),
+			'directory-blogs-loading'           => array(
+				'type'    => 'loading',
+				'message' => __( 'Loading the sites of the network. Please wait.', 'buddypress' ),
+			),
+			'directory-groups-loading'          => array(
+				'type'    => 'loading',
+				'message' => __( 'Loading the groups of the community. Please wait.', 'buddypress' ),
+			),
+			'groups-loop-none'                  => array(
+				'type'    => 'info',
+				'message' => __( 'Sorry, there were no groups found.', 'buddypress' ),
+			),
+			'group-activity-loading'            => array(
+				'type'    => 'loading',
+				'message' => __( 'Loading the group updates. Please wait.', 'buddypress' ),
+			),
+			'group-members-loading'             => array(
+				'type'    => 'loading',
+				'message' => __( 'Requesting the group members. Please wait.', 'buddypress' ),
+			),
+			'group-members-none'                => array(
+				'type'    => 'info',
+				'message' => __( 'Sorry, there were no group members found.', 'buddypress' ),
+			),
+			'group-members-search-none'         => array(
+				'type'    => 'info',
+				'message' => __( 'Sorry, there was no member of that name found in this group.', 'buddypress' ),
+			),
+			'group-manage-members-none'         => array(
+				'type'    => 'info',
+				'message' => __( 'This group has no members.', 'buddypress' ),
+			),
+			'group-requests-none'               => array(
+				'type'    => 'info',
+				'message' => __( 'There are no pending membership requests.', 'buddypress' ),
+			),
+			'group-requests-loading'            => array(
+				'type'    => 'loading',
+				'message' => __( 'Loading the members who requested to join the group. Please wait.', 'buddypress' ),
+			),
+			'group-delete-warning'              => array(
+				'type'    => 'warning',
+				'message' => __( 'WARNING: Deleting this group will completely remove ALL content associated with it. There is no way back. Please be careful with this option.', 'buddypress' ),
+			),
+			'group-avatar-delete-info'          => array(
+				'type'    => 'info',
+				'message' => __( 'If you\'d like to remove the existing group profile photo but not upload a new one, please use the delete group profile photo button.', 'buddypress' ),
+			),
+			'directory-members-loading'         => array(
+				'type'    => 'loading',
+				'message' => __( 'Loading the members of your community. Please wait.', 'buddypress' ),
+			),
+			'members-loop-none'                 => array(
+				'type'    => 'info',
+				'message' => __( 'Sorry, no members were found.', 'buddypress' ),
+			),
+			'member-requests-none'              => array(
+				'type'    => 'info',
+				'message' => __( 'You have no pending friendship requests.', 'buddypress' ),
+			),
+			'member-invites-none'               => array(
+				'type'    => 'info',
+				'message' => __( 'You have no outstanding group invites.', 'buddypress' ),
+			),
+			'member-notifications-none'         => array(
+				'type'    => 'info',
+				'message' => __( 'This member has no notifications.', 'buddypress' ),
+			),
+			'member-wp-profile-none'            => array(
+				'type'    => 'info',
+				/* translators: %s: member name */
+				'message' => __( '%s did not save any profile information yet.', 'buddypress' ),
+			),
+			'member-delete-account'             => array(
+				'type'    => 'warning',
+				'message' => __( 'Deleting this account will delete all of the content it has created. It will be completely unrecoverable.', 'buddypress' ),
+			),
+			'member-activity-loading'           => array(
+				'type'    => 'loading',
+				'message' => __( 'Loading the member\'s updates. Please wait.', 'buddypress' ),
+			),
+			'member-blogs-loading'              => array(
+				'type'    => 'loading',
+				'message' => __( 'Loading the member\'s blogs. Please wait.', 'buddypress' ),
+			),
+			'member-friends-loading'            => array(
+				'type'    => 'loading',
+				'message' => __( 'Loading the member\'s friends. Please wait.', 'buddypress' ),
+			),
+			'member-groups-loading'             => array(
+				'type'    => 'loading',
+				'message' => __( 'Loading the member\'s groups. Please wait.', 'buddypress' ),
+			),
+			'member-notifications-loading'      => array(
+				'type'    => 'loading',
+				'message' => __( 'Loading notifications. Please wait.', 'buddypress' ),
+			),
+			'member-group-invites-all'          => array(
+				'type'    => 'info',
+				'message' => __( 'Currently every member of the community can invite you to join their groups. If you are not comfortable with it, you can always restrict group invites to your friends only.', 'buddypress' ),
+			),
+			'member-group-invites-friends-only' => array(
+				'type'    => 'info',
+				'message' => __( 'Currently only your friends can invite you to groups. Uncheck the box to allow any member to send invites.', 'buddypress' ),
+			),
+			'member-invites-none'               => array(
+				'type'    => 'info',
+				'message' => __( 'There are no invitations to display.', 'buddypress' ),
+			),
+		)
+	);
 
 	if ( ! isset( $feedback_messages[ $feedback_id ] ) ) {
 		return false;
@@ -1229,6 +1238,7 @@ function bp_nouveau_get_signup_fields( $section = '' ) {
  * Get Some submit buttons data.
  *
  * @since 3.0.0
+ * @since 8.0.0 Adds the 'member-send-invite' button.
  *
  * @param string $action The action requested.
  *
@@ -1244,106 +1254,120 @@ function bp_nouveau_get_submit_button( $action = '' ) {
 	 * Filter the Submit buttons to add your own.
 	 *
 	 * @since 3.0.0
+	 * @since 8.0.0 Adds the 'member-send-invite' button.
 	 *
 	 * @param array $value The list of submit buttons.
 	 *
 	 * @return array|false
 	 */
-	$actions = apply_filters( 'bp_nouveau_get_submit_button', array(
-		'register' => array(
-			'before'     => 'bp_before_registration_submit_buttons',
-			'after'      => 'bp_after_registration_submit_buttons',
-			'nonce'      => 'bp_new_signup',
-			'attributes' => array(
-				'name'  => 'signup_submit',
-				'id'    => 'submit',
-				'value' => __( 'Complete Sign Up', 'buddypress' ),
+	$actions = apply_filters(
+		'bp_nouveau_get_submit_button',
+		array(
+			'register'                      => array(
+				'before'     => 'bp_before_registration_submit_buttons',
+				'after'      => 'bp_after_registration_submit_buttons',
+				'nonce'      => 'bp_new_signup',
+				'attributes' => array(
+					'name'  => 'signup_submit',
+					'id'    => 'submit',
+					'value' => __( 'Complete Sign Up', 'buddypress' ),
+				),
 			),
-		),
-		'member-profile-edit' => array(
-			'before' => '',
-			'after'  => '',
-			'nonce'  => 'bp_xprofile_edit',
-			'attributes' => array(
-				'name'  => 'profile-group-edit-submit',
-				'id'    => 'profile-group-edit-submit',
-				'value' => __( 'Save Changes', 'buddypress' ),
+			'member-profile-edit'           => array(
+				'before'     => '',
+				'after'      => '',
+				'nonce'      => 'bp_xprofile_edit',
+				'attributes' => array(
+					'name'  => 'profile-group-edit-submit',
+					'id'    => 'profile-group-edit-submit',
+					'value' => __( 'Save Changes', 'buddypress' ),
+				),
 			),
-		),
-		'member-capabilities' => array(
-			'before' => 'bp_members_capabilities_account_before_submit',
-			'after'  => 'bp_members_capabilities_account_after_submit',
-			'nonce'  => 'capabilities',
-			'attributes' => array(
-				'name'  => 'capabilities-submit',
-				'id'    => 'capabilities-submit',
-				'value' => __( 'Save', 'buddypress' ),
+			'member-capabilities'           => array(
+				'before'     => 'bp_members_capabilities_account_before_submit',
+				'after'      => 'bp_members_capabilities_account_after_submit',
+				'nonce'      => 'capabilities',
+				'attributes' => array(
+					'name'  => 'capabilities-submit',
+					'id'    => 'capabilities-submit',
+					'value' => __( 'Save', 'buddypress' ),
+				),
 			),
-		),
-		'member-delete-account' => array(
-			'before' => 'bp_members_delete_account_before_submit',
-			'after'  => 'bp_members_delete_account_after_submit',
-			'nonce'  => 'delete-account',
-			'attributes' => array(
-				'disabled' => 'disabled',
-				'name'     => 'delete-account-button',
-				'id'       => 'delete-account-button',
-				'value'    => __( 'Delete Account', 'buddypress' ),
+			'member-delete-account'         => array(
+				'before'     => 'bp_members_delete_account_before_submit',
+				'after'      => 'bp_members_delete_account_after_submit',
+				'nonce'      => 'delete-account',
+				'attributes' => array(
+					'disabled' => 'disabled',
+					'name'     => 'delete-account-button',
+					'id'       => 'delete-account-button',
+					'value'    => __( 'Delete Account', 'buddypress' ),
+				),
 			),
-		),
-		'members-general-settings' => array(
-			'before' => 'bp_core_general_settings_before_submit',
-			'after'  => 'bp_core_general_settings_after_submit',
-			'nonce'  => 'bp_settings_general',
-			'attributes' => array(
-				'name'  => 'submit',
-				'id'    => 'submit',
-				'value' => __( 'Save Changes', 'buddypress' ),
-				'class' => 'auto',
+			'members-general-settings'      => array(
+				'before'     => 'bp_core_general_settings_before_submit',
+				'after'      => 'bp_core_general_settings_after_submit',
+				'nonce'      => 'bp_settings_general',
+				'attributes' => array(
+					'name'  => 'submit',
+					'id'    => 'submit',
+					'value' => __( 'Save Changes', 'buddypress' ),
+					'class' => 'auto',
+				),
 			),
-		),
-		'member-notifications-settings' => array(
-			'before' => 'bp_members_notification_settings_before_submit',
-			'after'  => 'bp_members_notification_settings_after_submit',
-			'nonce'  => 'bp_settings_notifications',
-			'attributes' => array(
-				'name'  => 'submit',
-				'id'    => 'submit',
-				'value' => __( 'Save Changes', 'buddypress' ),
-				'class' => 'auto',
+			'member-notifications-settings' => array(
+				'before'     => 'bp_members_notification_settings_before_submit',
+				'after'      => 'bp_members_notification_settings_after_submit',
+				'nonce'      => 'bp_settings_notifications',
+				'attributes' => array(
+					'name'  => 'submit',
+					'id'    => 'submit',
+					'value' => __( 'Save Changes', 'buddypress' ),
+					'class' => 'auto',
+				),
 			),
-		),
-		'members-profile-settings' => array(
-			'before' => 'bp_core_xprofile_settings_before_submit',
-			'after'  => 'bp_core_xprofile_settings_after_submit',
-			'nonce'  => 'bp_xprofile_settings',
-			'attributes' => array(
-				'name'  => 'xprofile-settings-submit',
-				'id'    => 'submit',
-				'value' => __( 'Save Changes', 'buddypress' ),
-				'class' => 'auto',
+			'members-profile-settings'      => array(
+				'before'     => 'bp_core_xprofile_settings_before_submit',
+				'after'      => 'bp_core_xprofile_settings_after_submit',
+				'nonce'      => 'bp_xprofile_settings',
+				'attributes' => array(
+					'name'  => 'xprofile-settings-submit',
+					'id'    => 'submit',
+					'value' => __( 'Save Changes', 'buddypress' ),
+					'class' => 'auto',
+				),
 			),
-		),
-		'member-group-invites' => array(
-			'nonce'  => 'bp_nouveau_group_invites_settings',
-			'attributes' => array(
-				'name'  => 'member-group-invites-submit',
-				'id'    => 'submit',
-				'value' => __( 'Save', 'buddypress' ),
-				'class' => 'auto',
+			'member-group-invites'          => array(
+				'nonce'      => 'bp_nouveau_group_invites_settings',
+				'attributes' => array(
+					'name'  => 'member-group-invites-submit',
+					'id'    => 'submit',
+					'value' => __( 'Save', 'buddypress' ),
+					'class' => 'auto',
+				),
 			),
-		),
-		'activity-new-comment' => array(
-			'after'     => 'bp_activity_entry_comments',
-			'nonce'     => 'new_activity_comment',
-			'nonce_key' => '_wpnonce_new_activity_comment',
-			'wrapper'   => false,
-			'attributes' => array(
-				'name'  => 'ac_form_submit',
-				'value' => _x( 'Post', 'button', 'buddypress' ),
+			'member-send-invite'            => array(
+				'nonce'                   => 'bp_members_invitation_send_%d',
+				'nonce_placeholder_value' => bp_displayed_user_id() ? bp_displayed_user_id() : bp_loggedin_user_id(),
+				'attributes'              => array(
+					'name'  => 'member-send-invite-submit',
+					'id'    => 'submit',
+					'value' => __( 'Send', 'buddypress' ),
+					'class' => 'auto',
+				),
 			),
-		),
-	) );
+			'activity-new-comment'          => array(
+				'after'      => 'bp_activity_entry_comments',
+				'nonce'      => 'new_activity_comment',
+				'nonce_key'  => '_wpnonce_new_activity_comment',
+				'wrapper'    => false,
+				'attributes' => array(
+					'name'  => 'ac_form_submit',
+					'value' => _x( 'Post', 'button', 'buddypress' ),
+				),
+			),
+		)
+	);
 
 	if ( isset( $actions[ $action ] ) ) {
 		return $actions[ $action ];
diff --git src/bp-templates/bp-nouveau/includes/members/functions.php src/bp-templates/bp-nouveau/includes/members/functions.php
index 6160d33be..ee74cad6a 100644
--- src/bp-templates/bp-nouveau/includes/members/functions.php
+++ src/bp-templates/bp-nouveau/includes/members/functions.php
@@ -3,12 +3,34 @@
  * Members functions
  *
  * @since 3.0.0
- * @version 6.0.0
+ * @version 8.0.0
  */
 
 // Exit if accessed directly.
 defined( 'ABSPATH' ) || exit;
 
+/**
+ * Register Scripts for the Members component
+ *
+ * @since 8.0.0
+ *
+ * @param array $scripts Optional. The array of scripts to register.
+ * @return array The same array with the specific members scripts.
+ */
+function bp_nouveau_members_register_scripts( $scripts = array() ) {
+	if ( ! isset( $scripts['bp-nouveau'] ) || ! bp_get_members_invitations_allowed() ) {
+		return $scripts;
+	}
+
+	return array_merge( $scripts, array(
+		'bp-nouveau-member-invites' => array(
+			'file'         => 'js/buddypress-member-invites%s.js',
+			'dependencies' => array(),
+			'footer'       => true,
+		),
+	) );
+}
+
 /**
  * Enqueue the members scripts
  *
@@ -16,19 +38,20 @@ defined( 'ABSPATH' ) || exit;
  */
 function bp_nouveau_members_enqueue_scripts() {
 	// Neutralize Ajax when using BuddyPress Groups & member widgets on default front page
-	if ( ! bp_is_user_front() || ! bp_nouveau_get_appearance_settings( 'user_front_page' ) ) {
-		return;
+	if ( bp_is_user_front() && bp_nouveau_get_appearance_settings( 'user_front_page' ) ) {
+		wp_add_inline_style(
+			'bp-nouveau',
+			'#member-front-widgets #groups-list-options,
+			#member-front-widgets #members-list-options,
+			#member-front-widgets #friends-list-options {
+				display: none;
+			}'
+		);
 	}
 
-	wp_add_inline_style(
-		'bp-nouveau', '
-		#member-front-widgets #groups-list-options,
-		#member-front-widgets #members-list-options,
-		#member-front-widgets #friends-list-options {
-			display: none;
-		}
-	'
-	);
+	if ( bp_is_user_members_invitations_list() ) {
+		wp_enqueue_script( 'bp-nouveau-member-invites' );
+	}
 }
 
 /**
diff --git src/bp-templates/bp-nouveau/includes/members/loader.php src/bp-templates/bp-nouveau/includes/members/loader.php
index 0aca1fb52..6a13d1f30 100644
--- src/bp-templates/bp-nouveau/includes/members/loader.php
+++ src/bp-templates/bp-nouveau/includes/members/loader.php
@@ -88,6 +88,7 @@ class BP_Nouveau_Members {
 	protected function setup_filters() {
 		// Add the default-front to User's front hierarchy if user enabled it (Enabled by default).
 		add_filter( 'bp_displayed_user_get_front_template', 'bp_nouveau_member_reset_front_template', 10, 1 );
+		add_filter( 'bp_nouveau_register_scripts', 'bp_nouveau_members_register_scripts', 10, 1 );
 
 		// The number formatting is done into the `bp_nouveau_nav_count()` template tag.
 		remove_filter( 'bp_get_total_member_count', 'bp_core_number_format' );
diff --git src/bp-templates/bp-nouveau/includes/members/template-tags.php src/bp-templates/bp-nouveau/includes/members/template-tags.php
index a1eff11c4..bd578b3bb 100644
--- src/bp-templates/bp-nouveau/includes/members/template-tags.php
+++ src/bp-templates/bp-nouveau/includes/members/template-tags.php
@@ -3,7 +3,7 @@
  * Members template tags
  *
  * @since 3.0.0
- * @version 6.0.0
+ * @version 8.0.0
  */
 
 // Exit if accessed directly.
@@ -660,6 +660,8 @@ function bp_nouveau_member_template_part() {
 			$template = 'profile';
 		} elseif ( bp_is_user_notifications() ) {
 			$template = 'notifications';
+		} elseif ( bp_is_user_members_invitations() ) {
+			$template = 'invitations';
 		} elseif ( bp_is_user_settings() ) {
 			$template = 'settings';
 		}
@@ -1037,3 +1039,32 @@ function bp_nouveau_wp_profile_field_data() {
 		$field = bp_nouveau()->members->wp_profile_current;
 		return $field->data;
 	}
+
+/**
+ * Outputs the Invitations bulk actions dropdown list.
+ *
+ * @since 8.0.0
+ */
+function bp_nouveau_invitations_bulk_management_dropdown() {
+	?>
+	<div class="select-wrap">
+
+		<label class="bp-screen-reader-text" for="invitation-select">
+			<?php
+			esc_html_e( 'Select Bulk Action', 'buddypress' );
+			?>
+		</label>
+
+		<select name="invitation_bulk_action" id="invitation-select">
+			<option value="" selected="selected"><?php esc_html_e( 'Bulk Actions', 'buddypress' ); ?></option>
+			<option value="resend"><?php echo esc_html_x( 'Resend', 'button', 'buddypress' ); ?></option>
+			<option value="cancel"><?php echo esc_html_x( 'Cancel', 'button', 'buddypress' ); ?></option>
+		</select>
+
+		<span class="select-arrow"></span>
+
+	</div><!-- // .select-wrap -->
+
+	<input type="submit" id="invitation-bulk-manage" class="button action" value="<?php echo esc_attr_x( 'Apply', 'button', 'buddypress' ); ?>">
+	<?php
+}
diff --git src/bp-templates/bp-nouveau/includes/template-tags.php src/bp-templates/bp-nouveau/includes/template-tags.php
index c6f3fee76..76f978048 100644
--- src/bp-templates/bp-nouveau/includes/template-tags.php
+++ src/bp-templates/bp-nouveau/includes/template-tags.php
@@ -2641,14 +2641,19 @@ function bp_nouveau_submit_button( $action, $object_id = 0 ) {
 		printf( '<div class="submit">%s</div>', $submit_input );
 	}
 
+	$nonce = $submit_data['nonce'];
+	if ( isset( $submit_data['nonce_placeholder_value'] ) ) {
+		$nonce = sprintf( $nonce, $submit_data['nonce_placeholder_value'] );
+	}
+
 	if ( empty( $submit_data['nonce_key'] ) ) {
-		wp_nonce_field( $submit_data['nonce'] );
+		wp_nonce_field( $nonce );
 	} else {
 		if ( $object_id ) {
 			$submit_data['nonce_key'] .= '_' . (int) $object_id;
 		}
 
-		wp_nonce_field( $submit_data['nonce'], $submit_data['nonce_key'] );
+		wp_nonce_field( $nonce, $submit_data['nonce_key'] );
 	}
 
 	if ( ! empty( $submit_data['after'] ) ) {
diff --git src/bp-templates/bp-nouveau/js/buddypress-member-invites.js src/bp-templates/bp-nouveau/js/buddypress-member-invites.js
new file mode 100644
index 000000000..38c066b5e
--- /dev/null
+++ src/bp-templates/bp-nouveau/js/buddypress-member-invites.js
@@ -0,0 +1,67 @@
+/**
+ * Handles the dynamic parts of the Member's Pending Invitations screen.
+ *
+ * @since  8.0.0
+ * @version 8.0.0
+ */
+( function() {
+	/**
+	 * Organizes the dynamic parts of the Member's Pending Invitations screen.
+	 *
+	 * @namespace bp.Nouveau.Invitations
+	 * @memberof  bp.Nouveau
+	 *
+	 * @since  8.0.0
+	 * @type {Object}
+	 */
+	var Invitations = {
+		/**
+		 * Selects/Unselects all invitations.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param {Object} event The click event.
+		 */
+		toggleSelection: function( event ) {
+			document.querySelectorAll( '.invitation-check' ).forEach( function( cb ) {
+				cb.checked = event.target.checked;
+			} );
+		},
+		/**
+		 * Selects/Unselects all invitations.
+		 *
+		 * @since 8.0.0
+		 *
+		 * @param {Object} event The click event.
+		 */
+		toggleSubmit: function( event ) {
+			if ( ! event.target.value ) {
+				document.querySelector( '#invitation-bulk-manage' ).setAttribute( 'disabled', 'disabled' );
+			} else {
+				document.querySelector( '#invitation-bulk-manage' ).removeAttribute( 'disabled' );
+			}
+		},
+		/**
+		 * Adds listeners.
+		 *
+		 * @since 8.0.0
+		 */
+		start: function() {
+			// Disable the submit button.
+			document.querySelector( '#invitation-bulk-manage' ).setAttribute( 'disabled', 'disabled' );
+
+			// Select/UnSelect all invitations.
+			document.querySelector( '#select-all-invitations' ).addEventListener( 'click', this.toggleSelection );
+
+			// Enable/Disable the submit button.
+			document.querySelector( '#invitation-select' ).addEventListener( 'change', this.toggleSubmit );
+		}
+	};
+
+	window.bp = window.bp || {};
+	if ( window.bp.Nouveau ) {
+		window.bp.Nouveau.Invitations = Invitations;
+
+		Invitations.start();
+	}
+} )();
diff --git src/bp-templates/bp-nouveau/sass/twentytwentyone.scss src/bp-templates/bp-nouveau/sass/twentytwentyone.scss
index af56e9a79..2bc6a8de3 100644
--- src/bp-templates/bp-nouveau/sass/twentytwentyone.scss
+++ src/bp-templates/bp-nouveau/sass/twentytwentyone.scss
@@ -221,12 +221,14 @@ Hello, this is the BP Nouveau's Twenty Twenty-One companion stylesheet.
 		}
 	}
 
-	.notifications-options-nav {
+	.notifications-options-nav,
+	.invitations-options-nav {
 		margin-top: 1em;
+	}
 
-		input#notification-bulk-manage {
-			line-height: 1.2;
-		}
+	.notifications-options-nav input#notification-bulk-manage,
+	.invitations-options-nav input#invitation-bulk-manage {
+		line-height: 1.2;
 	}
 }
 
diff --git src/class-buddypress.php src/class-buddypress.php
index 1af41585b..789cc418a 100644
--- src/class-buddypress.php
+++ src/class-buddypress.php
@@ -622,6 +622,8 @@ class BuddyPress {
 			'BP_REST_Attachments_Member_Avatar_Endpoint' => 'members',
 			'BP_REST_Attachments_Member_Cover_Endpoint'  => 'members',
 			'BP_REST_Signup_Endpoint'                    => 'members',
+			'BP_Members_Invitation_Manager'              => 'members',
+			'BP_Members_Invitations_Template'            => 'members',
 
 			'BP_REST_Messages_Endpoint' => 'messages',
 
