diff --git a/docs/dl-query.md b/docs/dl-query.md
new file mode 100644
index 000000000..23f93c121
--- /dev/null
+++ b/docs/dl-query.md
@@ -0,0 +1,29 @@
+# DL-Query
+
+## Contents
+
+1. [Overview](#overview)
+2. [Query types](#query-types)
+
+## Overview
+
+ROBOT can execute DL queries against an ontology. The functionality closely mimics the functionality of the DL Query Tab in Protege.
+
+The `dl-query` command can be used to query for ancestors, descendants, instances and other relatives of an OWL Class Expression that is provided in Manchester syntax.
+
+The output is always a list of Entity IRIs. Multiple queries and output files can be supplied. For example:
+
+ robot query --input uberon_module.owl \
+ --query "'part_of' some 'subdivision of trunk'" part_of_subdiv_trunk.txt \
+ --query "'part_of' some 'nervous system'" part_of_nervous_system.txt
+
+## Query Types
+
+The following query types are currently supported:
+
+- equivalents: Classes that are exactly equivalent to the supplied class expression
+- parents: Direct parents (superclasses) of the class expression provided
+- children: Direct children (subclasses) of the class expression provided
+- descendants (default): All subclasses of the class expression provided
+- ancestors: All superclasses of the class expression provided
+- instances: All named individuals that are instances of the class expression provided
diff --git a/robot-command/src/main/java/org/obolibrary/robot/DLQueryCommand.java b/robot-command/src/main/java/org/obolibrary/robot/DLQueryCommand.java
new file mode 100644
index 000000000..9f3d561b9
--- /dev/null
+++ b/robot-command/src/main/java/org/obolibrary/robot/DLQueryCommand.java
@@ -0,0 +1,174 @@
+package org.obolibrary.robot;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.io.FileUtils;
+import org.obolibrary.robot.exceptions.InconsistentOntologyException;
+import org.semanticweb.owlapi.apibinding.OWLManager;
+import org.semanticweb.owlapi.model.*;
+import org.semanticweb.owlapi.reasoner.OWLReasoner;
+import org.semanticweb.owlapi.reasoner.OWLReasonerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Handles inputs and outputs for the {@link DLQueryOperation}.
+ *
+ * @author Nicolas Matentzoglu
+ */
+public class DLQueryCommand implements Command {
+ /** Logger. */
+ private static final Logger logger = LoggerFactory.getLogger(DLQueryCommand.class);
+
+ private static final String NS = "dl-query#";
+
+ private static final List LEGAL_RELATIONS =
+ Arrays.asList("equivalents", "ancestors", "descendants", "instances", "parents", "children");
+ OWLDataFactory df = OWLManager.getOWLDataFactory();
+
+ private static final String maxTypeError = NS + "MAX TYPE ERROR --max ('%s') must be an integer";
+ private static final String illegalRelationError =
+ NS + "ILLEGAL RELATION ERROR: %s. Must be one of " + String.join(" ", LEGAL_RELATIONS) + ".";
+ private static final String missingQueryArgumentError =
+ NS + "MISSING QUERY ARGUMENT ERROR: must have a valid --query.";
+
+ /** Error message when --query does not have two arguments. */
+ private static final String missingOutputError =
+ NS + "MISSING OUTPUT ERROR --%s requires two arguments: query and output";
+
+ /** Error message when a query is not provided */
+ private static final String missingQueryError =
+ NS + "MISSING QUERY ERROR at least one query must be provided";
+
+ /** Store the command-line options for the command. */
+ private Options options;
+
+ public DLQueryCommand() {
+ Options o = CommandLineHelper.getCommonOptions();
+ o.addOption("i", "input", true, "load ontology from a file");
+ o.addOption("I", "input-iri", true, "load ontology from an IRI");
+ o.addOption("r", "reasoner", true, "reasoner to use: ELK, HermiT, JFact");
+
+ Option opt = new Option("q", "query", true, "the DL query to run");
+ opt.setArgs(2);
+ o.addOption(opt);
+
+ o.addOption(
+ "s",
+ "select",
+ true,
+ "select what relations to query: equivalents, parents, children, ancestors, descendants, instances");
+ o.addOption("o", "output", true, "save ontology containing only explanation axioms to a file");
+ options = o;
+ }
+
+ @Override
+ public String getName() {
+ return "dl-query";
+ }
+
+ @Override
+ public String getDescription() {
+ return "query the ontology with the given class expression";
+ }
+
+ @Override
+ public String getUsage() {
+ return "robot dl-query --input --query --output