Inversion of control is a design paradigm with the goal of giving more control to the targeted components of your application, the ones getting the work done. In a traditional top down designed system, not only is the system designed that way, but because it is, the logical control of the application flows from the top components, the ones designed first, to the ones designed last, the components usually doing any real work. Inversion of control somewhat literally is giving control of the application to the operation specific components.
Dependency injection is a pattern used to create instances of objects that other objects rely on without knowing at compile time which class will be used to provide that functionality. Inversion of control relies on dependency injection because a mechanism is needed in order to activate the components providing the specific functionality. How does the framework know which components to create if it is no longer in control?
A great example of these concepts at work is the plug-in framework in Reflector. The plug-ins have much more control of the system even though they are the same code doing the work. The application framework allows access to its functionality through a variety of service providers. A plug-in is given a reference to the service providers when it is created. Through those providers, the plug-in has the ability to add its own menu items, change how files are displayed, display its own information in the appropriate panels, etc. Control has been taken from the main application and given to the component doing the specific work; inversion of control.
How does the application know to create those plug-ins and how is the code executed? Dependency injection is your answer. A factory creates the plug-ins that implement a specific interface using configuration information, reflection and the Activator object (in .NET at least). The instance that is created, the dependency, is injected into a reference, or in this case a collection of all of the running plug-ins. A single method is called on each of those plug-ins, Initialize if memory serves, which passes control over to the plug-in. The framework doesn't know what they will do, it just lets them do it.
The two concepts work together in this way to allow for much more flexible, reusable, and encapsulated code to be written. As such, they are important concepts in designing object oriented solutions.