diff --git a/data/model.py b/data/model.py
index 7dbf578a5..94c71e67e 100644
--- a/data/model.py
+++ b/data/model.py
@@ -348,6 +348,12 @@ def get_organization_team(orgname, teamname):
   return result[0]
 
 
+def get_organization_members_with_teams(organization):
+  joined = TeamMember.select().annotate(Team).annotate(User)
+  query = joined.where(Team.organization == organization)
+  return query
+
+
 def get_organization_team_members(teamid):
   joined = User.select().join(TeamMember).join(Team)
   query = joined.where(Team.id == teamid)
diff --git a/endpoints/api.py b/endpoints/api.py
index 36a32053f..5a760137e 100644
--- a/endpoints/api.py
+++ b/endpoints/api.py
@@ -307,6 +307,31 @@ def get_organization(orgname):
 
   abort(403)
 
+@app.route('/api/organization/<orgname>/members', methods=['GET'])
+@api_login_required
+def get_organization_members(orgname):
+  permission = AdministerOrganizationPermission(orgname)
+  if permission.can():    
+    try:
+      org = model.get_organization(orgname)
+    except model.InvalidOrganizationException:
+      abort(404)
+      
+    # Loop to create the members dictionary. Note that the members collection
+    # will return an entry for *every team* a member is on, so we will have
+    # duplicate keys (which is why we pre-build the dictionary).
+    members_dict = {}
+    members = model.get_organization_members_with_teams(org)    
+    for member in members:
+      if not member.user.username in members_dict:
+        members_dict[member.user.username] = {'username': member.user.username, 'teams': []}
+    
+      members_dict[member.user.username]['teams'].append(member.team.name)        
+
+    return jsonify({'members': members_dict})
+
+  abort(403)
+
 @app.route('/api/organization/<orgname>/private', methods=['GET'])
 @api_login_required
 def get_organization_private_allowed(orgname):
diff --git a/static/css/quay.css b/static/css/quay.css
index c51a6c320..0fead2172 100644
--- a/static/css/quay.css
+++ b/static/css/quay.css
@@ -1514,7 +1514,6 @@ p.editable:hover i {
   100% { background-color: rgba(92, 184, 92, 0.36); }
 }
 
-
 .org-view .team-title { 
   font-size: 20px;
   text-transform: capitalize;
@@ -1533,6 +1532,33 @@ p.editable:hover i {
   padding: 6px;
 }
 
+.org-admin .team-link {
+  display: inline-block;
+  text-transform: capitalize;
+  margin-right: 20px;
+}
+
+.org-admin #members table td {
+  font-size: 16px;
+}
+
+.org-admin #members table i {
+  margin-right: 4px;
+}
+
+.org-admin #members .side-controls {
+  float: right;
+}
+
+.org-admin #members .result-count {
+  display: inline-block;
+  margin-right: 10px;
+}
+
+.org-admin #members .filter-input {
+  display: inline-block;
+}
+
 .plan-manager-element .plans-table thead td {
   color: #aaa;
   font-weight: bold;
diff --git a/static/js/controllers.js b/static/js/controllers.js
index ada86a872..87b6bd220 100644
--- a/static/js/controllers.js
+++ b/static/js/controllers.js
@@ -1109,7 +1109,28 @@ function OrgAdminCtrl($rootScope, $scope, Restangular, $routeParams, UserService
   });
 
   var orgname = $routeParams.orgname;
+
   $scope.orgname = orgname;
+  $scope.membersLoading = true;
+  $scope.membersFound = null;
+
+  $scope.loadMembers = function() {
+    if ($scope.membersFound) { return; }
+    $scope.membersLoading = true;
+    
+    var getMembers = Restangular.one(getRestUrl('organization', orgname, 'members'));
+    getMembers.get().then(function(resp) {
+      var membersArray = [];
+      for (var key in resp.members) {
+        if (resp.members.hasOwnProperty(key)) {
+          membersArray.push(resp.members[key]);
+        }
+      }
+
+      $scope.membersFound = membersArray;
+      $scope.membersLoading = false;
+    });
+  };
 
   var loadOrganization = function() {
     var getOrganization = Restangular.one(getRestUrl('organization', orgname));
diff --git a/static/partials/org-admin.html b/static/partials/org-admin.html
index 4f1a77210..c9811e82a 100644
--- a/static/partials/org-admin.html
+++ b/static/partials/org-admin.html
@@ -14,7 +14,7 @@
     <div class="col-md-2">
       <ul class="nav nav-pills nav-stacked">
         <li class="active"><a href="javascript:void(0)" data-toggle="tab" data-target="#plan">Plan and Usage</a></li>
-        <li><a href="javascript:void(0)" data-toggle="tab" data-target="#members">Members</a></li>
+        <li><a href="javascript:void(0)" data-toggle="tab" data-target="#members" ng-click="loadMembers()">Members</a></li>
       </ul>
     </div>
 
@@ -28,7 +28,38 @@
 
         <!-- Members tab -->
         <div id="members" class="tab-pane">
-          members
+          <i class="fa fa-spinner fa-spin fa-3x" ng-show="membersLoading"></i>
+
+          <div ng-show="!membersLoading">
+            <div class="side-controls">      
+              <div class="result-count">
+                Showing {{(membersFound | filter:search | limitTo:50).length}} of {{(membersFound | filter:search).length}} matching members
+              </div>
+              <div class="filter-input">        
+                <input id="member-filter" class="form-control" placeholder="Filter Members" type="text" ng-model="search.$">
+              </div>
+            </div> 
+
+            <table class="table table-striped">
+              <thead>
+                <th>User</th>
+                <th>Teams</th>
+              </thead>
+              
+              <tr ng-repeat="memberInfo in (membersFound | filter:search | limitTo:50)">
+                <td>
+                  <i class="fa fa-user"></i>
+                  {{ memberInfo.username }}
+                </td>
+                <td>
+                  <span class="team-link" ng-repeat="team in memberInfo.teams">
+                    <i class="fa fa-group"></i>
+                    <a href="/organization/{{ organization.name }}/teams/{{ team }}">{{ team }}</a>
+                  </span>
+                </td>
+              </tr>
+            </table>
+          </div>
         </div>
       </div>
     </div>