diff --git a/test/test_instance.py b/test/test_instance.py
--- a/test/test_instance.py
+++ b/test/test_instance.py
@@ -10,7 +10,7 @@
 
 import mock
 
-from testCloud import instance, config
+from testCloud import instance, image, config
 
 class TestInstance:
 
@@ -42,27 +42,28 @@
 
     def test_non_existant_instance(self, monkeypatch):
         ref_name = 'test-123'
-        ref_image = 'someimage.qcow2'
+        ref_image = image.Image('file:///someimage.qcow2')
 
         stub_listdir = mock.Mock()
         stub_listdir.return_value = []
         monkeypatch.setattr(os, 'listdir', stub_listdir)
 
-        test_instance = instance.find_instance_path(ref_name, ref_image)
+        test_instance = instance.find_instance(ref_name, ref_image)
 
         assert test_instance is None
 
 
     def test_find_exist_instance(self, monkeypatch):
         ref_name = 'test-123'
-        ref_image = 'someimage.qcow2'
+        ref_image = image.Image('file:///someimage.qcow2')
         ref_path = os.path.join(self.conf.DATA_DIR,
                                 'instances/{}'.format(ref_name))
 
         stub_listdir = mock.Mock()
         stub_listdir.return_value = [ref_name]
         monkeypatch.setattr(os, 'listdir', stub_listdir)
 
-        test_instance = instance.find_instance_path(ref_name, ref_image)
+        test_instance = instance.find_instance(ref_name, ref_image)
+
+        assert test_instance.path == ref_path
 
-        assert test_instance == ref_path
diff --git a/testCloud/cli.py b/testCloud/cli.py
--- a/testCloud/cli.py
+++ b/testCloud/cli.py
@@ -13,8 +13,6 @@
 import sys
 from pprint import pprint
 
-import libvirt
-
 from . import config
 from . import image
 from . import instance
@@ -45,11 +43,15 @@
 
     :param args: args from argparser
     """
-    log.debug("list instance")
     instances = instance.list_instances()
-    print("Current Instances:")
-    for inst in instances:
-        print("  {}".format(inst))
+
+    print("{:<40} {:<10}".format("Name", "State"))
+    print("--------------------------------------------------")
+    for inst in instances.keys():
+        if args.all or instances[inst] == 'running':
+            print("{:<40} {:<10}".format(inst, instances[inst]))
+
+    print("")
 
 def _create_instance(args):
     """Handler for 'instance create' command. Expects the following elements in args:
@@ -64,15 +66,15 @@
     tc_image = image.Image(args.url)
     tc_image.prepare()
 
-    instance_path = instance.find_instance_path(args.name, tc_image.name)
+    existing_instance = instance.find_instance(args.name, tc_image)
 
     # can't create existing instances
-    if instance_path is not None:
+    if existing_instance is not None:
         raise TestCloudCliError("A testCloud instance named {} already "\
                                 "exists at {}. Use 'testcloud instance start "\
                                 "{}' to start the instance or remove it before"\
                                 " re-creating ".format(args.name,
-                                                       instance_path,
+                                                       existing_instance.path,
                                                        args.name))
 
     else:
@@ -156,6 +158,9 @@
     #instance list
     instarg_list = instarg_subp.add_parser("list", help="list instances")
     instarg_list.set_defaults(func=_list_instance)
+    instarg_list.add_argument("--all",
+                              help="list all instances, running and stopped",
+                              action="store_true")
 
     #instance start
     instarg_start = instarg_subp.add_parser("start", help="start instance")
diff --git a/testCloud/instance.py b/testCloud/instance.py
--- a/testCloud/instance.py
+++ b/testCloud/instance.py
@@ -14,36 +14,87 @@
 import subprocess
 import glob
 import logging
+from pprint import pprint
+
+import libvirt
 
 from . import config
 from .exceptions import TestCloudInstanceError
 
 config_data = config.get_config()
 
 log = logging.getLogger('testCloud.instance')
 
-def find_instance_path(name, image):
+# mapping libvirt constants to a known set of strings
+DOMAIN_STATUS_ENUM = { libvirt.VIR_DOMAIN_NOSTATE: 'no state',
+                       libvirt.VIR_DOMAIN_RUNNING: 'running',
+                       libvirt.VIR_DOMAIN_BLOCKED: 'blocked',
+                       libvirt.VIR_DOMAIN_PAUSED:  'paused',
+                       libvirt.VIR_DOMAIN_SHUTDOWN: 'shutdown',
+                       libvirt.VIR_DOMAIN_SHUTOFF: 'shutoff',
+                       libvirt.VIR_DOMAIN_CRASHED: 'crashed',
+                       libvirt.VIR_DOMAIN_PMSUSPENDED: 'suspended'
+                       }
+
+
+def _list_instances():
+    """List existing instances currently known to testcloud
+
+    :returns: list of instance names
+    """
+
     instance_dir = '{}/instances'.format(config_data.DATA_DIR)
-    instances = os.listdir(instance_dir)
+    return os.listdir(instance_dir)
 
-    for inst in instances:
-        if name == inst:
-            return os.path.join(instance_dir, inst)
+def _list_system_domains(connection):
+    """List known domains for a given hypervisor connection.
 
-    return None
+    :param connection: libvirt compatible hypervisor connection
+    :returns: dictionary mapping of name:state
+    :rtype: dict
+    """
+
+    domains = {}
+    conn = libvirt.openReadOnly(connection)
+    for domain in conn.listAllDomains():
+        # the libvirt docs seem to indicate that the second int is for state
+        # details, only used when state is ERROR, so only looking at the first
+        # int returned for domain.state()
+
+        domains[domain.name()] = DOMAIN_STATUS_ENUM[domain.state()[0]]
+
+    return domains
 
 def find_instance(name, image):
-    instance_dir = '{}/instances'.format(config_data.DATA_DIR)
-    instances = os.listdir(instance_dir)
+    """Find an instance using a given name and image, if it exists.
+
+    :param name: name of instance to find
+    :param image: :py:class:`testCloud.image.Image`
+    :returns: :py:class:`Instance` if the instance exists, None if it doesn't
+    """
+
+    instances = _list_instances()
     for inst in instances:
         if name == inst:
             return Instance(name, image)
     return None
 
-
-def list_instances():
-    instance_dir = '{}/instances'.format(config_data.DATA_DIR)
-    instances = os.listdir(instance_dir)
+def list_instances(connection='qemu:///system'):
+    """List instances known by testCloud and the state of each instance
+
+    :param connection: libvirt compatible connection to use when listing domains
+    :returns: dictionary of instance_name to domain_state mapping
+    """
+    system_domains = _list_system_domains(connection)
+    all_instances = _list_instances()
+
+    instances = {}
+    for instance in all_instances:
+        if instance not in all_instances:
+            raise TestCloudInstanceError("instance {} exists in instances/ "\
+                                         "but is not a libvirt domain on "\
+                                         "{}".format(instance, connection))
+        instances[instance] = system_domains[instance]
 
     return instances
 

