diff --git a/inventory_provider/routes/msr.py b/inventory_provider/routes/msr.py
index 5b28b7a6b5aada58fb371c808d71709f0d69e7a3..8c052a67f30d3f540375a2666c9b5ffd460fb3d9 100644
--- a/inventory_provider/routes/msr.py
+++ b/inventory_provider/routes/msr.py
@@ -74,7 +74,13 @@ These endpoints are intended for use by MSR.
 /msr/vpn-proxy
 --------------------------------------------
 
-.. autofunction:: inventory_provider.routes.msr.vpn-proxy
+.. autofunction:: inventory_provider.routes.msr.vpn_proxy
+
+
+/msr/asn-peers
+--------------------------------------------
+
+.. autofunction:: inventory_provider.routes.msr.asn_peers
 
 
 helpers
@@ -356,6 +362,40 @@ DOMAIN_TO_POP_MAPPING = {
     "ams.nl": "Amsterdam"
 }
 
+# very similar to PEERING_LIST_SCHEMA but
+# with a field for NREN, which is required
+ASN_PEER_LIST_SCHEMA = {
+    '$schema': 'http://json-schema.org/draft-07/schema#',
+    'definitions': {
+        'peering-instance': {
+            'type': 'object',
+            'properties': {
+                'address': {'type': 'string'},
+                'description': {'type': 'string'},
+                'logical-system': {'type': 'string'},
+                'group': {'type': 'string'},
+                'hostname': {'type': 'string'},
+                'remote-asn': {'type': 'integer'},
+                'local-asn': {'type': 'integer'},
+                'instance': {'type': 'string'},
+                'nren': {'type': 'string'}
+            },
+            # only vrr peerings have remote-asn
+            # only group peerings have local-asn or instance
+            # not all group peerings have 'description'
+            # and only vrr or vpn-proxy peerings are within a logical system
+            'required': [
+                'address',
+                'group',
+                'hostname',
+                'nren'],
+            'additionalProperties': False
+        }
+    },
+    'type': 'array',
+    'items': {'$ref': '#/definitions/peering-instance'}
+}
+
 
 @routes.after_request
 def after_request(resp):
@@ -1173,3 +1213,88 @@ def vpn_proxy():
         peerings = list(_format_peerings(vpnproxy))
         response = json.dumps(peerings)
     return Response(response, mimetype='application/json')
+
+
+@routes.route('/asn-peers', methods=['GET', 'POST'], defaults={'asn': None})
+@routes.route('/asn-peers/<int:asn>', methods=['GET', 'POST'])
+@common.require_accepts_json
+def asn_peers(asn):
+    """
+    Handler for `/asn-peers`
+
+    This method returns a list of all peers filtered by `group` and `instance`,
+    which can be passed either as URL query parameters or as entries in a
+    POST request with a JSON body that matches this schema:
+    `{
+        "group": "group to filter by",
+        "instance": "instance to filter by"
+    }`
+    Results are returned where all filters given are true, and exact string
+    matches.
+
+    An optional URL parameter can be used to also filter by a specific ASN.
+
+    The response will be formatted according to the following schema:
+
+    .. asjson::
+       inventory_provider.routes.msr.ASN_PEER_LIST_SCHEMA
+
+    :param asn: specific ASN to get peers for
+    :return:
+    """
+    r = common.get_current_redis()
+
+    def _get_filtered_peers_for_asn(asn, nren, group, instance):
+        peers = json.loads(r.get(f'juniper-peerings:peer-asn:{asn}'))
+
+        def _attribute_filter(peer, name, value):
+            if value is None:
+                return True  # no filter parameter given in request
+            if name not in peer:
+                return False  # no value exists, cannot meet condition
+            return peer[name] == value
+
+        for peer in peers:
+            if _attribute_filter(peer, "group", group) and \
+                    _attribute_filter(peer, "instance", instance):
+                peer['nren'] = nren
+                yield peer
+
+    def _get_filtered_peers(asn_nren_map, group, instance):
+        for asn, nren in asn_nren_map.items():
+            asn_peers = _get_filtered_peers_for_asn(asn, nren, group, instance)
+            for peer in asn_peers:
+                yield peer
+
+    # handle getting parameters regardless of method of input
+    if request.method == 'GET':
+        group = request.args.get('group')
+        instance = request.args.get('instance')
+    else:
+        params = json.loads(request.json)
+        group = params.get('group', None)
+        instance = params.get('instance', None)
+
+    cache_key = f'classifier-cache:msr:asn-peers:{asn}:{group}:{instance}'
+    response = _ignore_cache_or_retrieve(request, cache_key, r)
+
+    if not response:
+        config = current_app.config['INVENTORY_PROVIDER_CONFIG']
+        # set up quick lookup based on ASN
+        asn_nren_map = {
+            item['asn']: item['nren'] for item in config['nren-asn-map']
+        }
+
+        if asn is not None:
+            nren = asn_nren_map.get(asn, None)
+            peers = list(
+                _get_filtered_peers_for_asn(asn, nren, group, instance)
+            )
+        else:
+            peers = list(
+                _get_filtered_peers(asn_nren_map, group, instance)
+            )
+        response = json.dumps(peers)
+        r.set(cache_key, response.encode('utf-8'))
+
+    return Response(response, mimetype='application/json')
diff --git a/test/conftest.py b/test/conftest.py
index 4e6d794b9c1417fee51526d360f79ed58a04c844..c95e25c6ce8af247f6e92ea9f5a8d633500d5d50 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -72,6 +72,10 @@ def data_config_filename():
                 {
                     "nren": "BAT",
                     "asn": 2200
+                },
+                {
+                    "nren": "BAZ",
+                    "asn": 1853
                 }
             ]
         }
diff --git a/test/test_msr_routes.py b/test/test_msr_routes.py
index b47c09307be1458eb1c0706ca0476138cc75a9ac..25bd97f80e88357c737a49998c2312b0858128e1 100644
--- a/test/test_msr_routes.py
+++ b/test/test_msr_routes.py
@@ -6,7 +6,7 @@ import pytest
 from inventory_provider.routes.msr import PEERING_LIST_SCHEMA, \
     PEERING_GROUP_LIST_SCHEMA, PEERING_ADDRESS_SERVICES_LIST, \
     SYSTEM_CORRELATION_SERVICES_LIST_SCHEMA, _get_services_for_address, \
-    MDVPN_LIST_SCHEMA, VPN_PROXY_LIST_SCHEMA
+    MDVPN_LIST_SCHEMA, VPN_PROXY_LIST_SCHEMA, ASN_PEER_LIST_SCHEMA
 from inventory_provider.routes.poller import SERVICES_LIST_SCHEMA
 from inventory_provider.tasks.common import _get_redis
 
@@ -346,3 +346,48 @@ def test_get_vpn_proxy_peerings(client, mocked_redis):
     response_data = json.loads(rv.data.decode('utf-8'))
     jsonschema.validate(response_data, VPN_PROXY_LIST_SCHEMA)
     assert response_data  # test data is non-empty
+
+
+@pytest.mark.parametrize('endpoint_variant', [
+    "",  # default, no filter
+    "/1853",
+    "?group=IAS-NRENS",
+    "?instance=IAS",
+    "?group=IAS-NRENS&instance=IAS",
+    "/1853?group=IAS-NRENS",
+    "/1853?instance=IAS",
+    "/1853?group=IAS-NRENS&instance=IAS"
+])
+def test_get_asn_peers_get(endpoint_variant, client, mocked_redis):
+    rv = client.get(
+        f'/msr/asn-peers{endpoint_variant}',
+        headers=DEFAULT_REQUEST_HEADERS
+    )
+    assert rv.status_code == 200
+    assert rv.is_json
+    response_data = json.loads(rv.data.decode('utf-8'))
+    jsonschema.validate(response_data, ASN_PEER_LIST_SCHEMA)
+    assert response_data  # test data is non-empty
+
+
+@pytest.mark.parametrize('endpoint_variant,post_body', [
+    ("", '{}'),
+    ("", '{"group": "IAS-NRENS"}'),
+    ("", '{"instance": "IAS"}'),
+    ("", '{"group": "IAS-NRENS", "instance": "IAS"}'),
+    ("/1853", '{}'),
+    ("/1853", '{"group": "IAS-NRENS"}'),
+    ("/1853", '{"instance": "IAS"}'),
+    ("/1853", '{"group": "IAS-NRENS", "instance": "IAS"}')
+])
+def test_get_asn_peers_post(endpoint_variant, post_body, client, mocked_redis):
+    rv = client.post(
+        f'/msr/asn-peers{endpoint_variant}',
+        headers=DEFAULT_REQUEST_HEADERS,
+        json=post_body
+    )
+    assert rv.status_code == 200
+    assert rv.is_json
+    response_data = json.loads(rv.data.decode('utf-8'))
+    jsonschema.validate(response_data, ASN_PEER_LIST_SCHEMA)
+    assert response_data  # test data is non-empty