diff --git a/wa/instrumentation/hwmon.py b/wa/instrumentation/hwmon.py
new file mode 100644
index 00000000..6530686b
--- /dev/null
+++ b/wa/instrumentation/hwmon.py
@@ -0,0 +1,88 @@
+#    Copyright 2017 ARM Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+from devlib import HwmonInstrument as _Instrument
+
+from wa import Instrument
+from wa.framework.instrumentation import fast
+
+MOMENTARY_QUANTITIES = ['temperature', 'power', 'voltage', 'current', 'fps']
+CUMULATIVE_QUANTITIES = ['energy', 'tx', 'tx/rx', 'frames']
+
+class HwmonInstrument(Instrument):
+    name = 'hwmon'
+
+    description = """
+    Hardware Monitor (hwmon) is a generic Linux kernel subsystem,
+    providing access to hardware monitoring components like temperature or
+    voltage/current sensors.
+
+    Data from hwmon that are a snapshot of a fluctuating value, such as
+    temperature and voltage, are reported once at the beginning and once at the
+    end of the workload run. Data that are a cumulative total of a quantity,
+    such as energy (which is the cumulative total of power consumption), are
+    reported as the difference between the values at the beginning and at the
+    end of the workload run.
+
+    There is currently no functionality to filter sensors: all of the available
+    hwmon data will be reported.
+    """
+
+    def initialize(self, context):
+        self.instrument = _Instrument(self.target)
+
+    def setup(self, context):
+        self.instrument.reset()
+
+    @fast
+    def start(self, context):
+        self.before = self.instrument.take_measurement()
+
+    @fast
+    def stop(self, context):
+        self.after = self.instrument.take_measurement()
+
+    def update_result(self, context):
+        measurements_before = {m.channel.label: m for m in self.before}
+        measurements_after = {m.channel.label: m for m in self.after}
+
+        if measurements_before.keys() != measurements_after.keys():
+            self.logger.warning(
+                'hwmon before/after measurements returned different entries!')
+
+        for label, measurement_after in measurements_after.iteritems():
+            if label not in measurements_before:
+                continue # We've already warned about this
+            measurement_before = measurements_before[label]
+
+            if measurement_after.channel.kind in MOMENTARY_QUANTITIES:
+                context.add_metric('{}_before'.format(label),
+                                   measurement_before.value,
+                                   measurement_before.channel.units)
+                context.add_metric('{}_after'.format(label),
+                                   measurement_after.value,
+                                   measurement_after.channel.units)
+
+            elif measurement_after.channel.kind in CUMULATIVE_QUANTITIES:
+                diff = measurement_after.value - measurement_before.value
+                context.add_metric(label, diff, measurement_after.channel.units)
+
+            else:
+                self.logger.warning(
+                    "Don't know what to do with hwmon channel '{}'"
+                    .format(measurement_after.channel))
+
+    def teardown(self, context):
+        self.instrument.teardown()